|
Packit |
c4476c |
#! /usr/bin/env perl
|
|
Packit |
c4476c |
# Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# Licensed under the OpenSSL license (the "License"). You may not use
|
|
Packit |
c4476c |
# this file except in compliance with the License. You can obtain a copy
|
|
Packit |
c4476c |
# in the file LICENSE in the source distribution or at
|
|
Packit |
c4476c |
# https://www.openssl.org/source/license.html
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# ====================================================================
|
|
Packit |
c4476c |
# Written by David S. Miller and Andy Polyakov
|
|
Packit |
c4476c |
# The module is licensed under 2-clause BSD license.
|
|
Packit |
c4476c |
# November 2012. All rights reserved.
|
|
Packit |
c4476c |
# ====================================================================
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
######################################################################
|
|
Packit |
c4476c |
# Montgomery squaring-n-multiplication module for SPARC T4.
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# The module consists of three parts:
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# 1) collection of "single-op" subroutines that perform single
|
|
Packit |
c4476c |
# operation, Montgomery squaring or multiplication, on 512-,
|
|
Packit |
c4476c |
# 1024-, 1536- and 2048-bit operands;
|
|
Packit |
c4476c |
# 2) collection of "multi-op" subroutines that perform 5 squaring and
|
|
Packit |
c4476c |
# 1 multiplication operations on operands of above lengths;
|
|
Packit |
c4476c |
# 3) fall-back and helper VIS3 subroutines.
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# RSA sign is dominated by multi-op subroutine, while RSA verify and
|
|
Packit |
c4476c |
# DSA - by single-op. Special note about 4096-bit RSA verify result.
|
|
Packit |
c4476c |
# Operands are too long for dedicated hardware and it's handled by
|
|
Packit |
c4476c |
# VIS3 code, which is why you don't see any improvement. It's surely
|
|
Packit |
c4476c |
# possible to improve it [by deploying 'mpmul' instruction], maybe in
|
|
Packit |
c4476c |
# the future...
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# Performance improvement.
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# 64-bit process, VIS3:
|
|
Packit |
c4476c |
# sign verify sign/s verify/s
|
|
Packit |
c4476c |
# rsa 1024 bits 0.000628s 0.000028s 1592.4 35434.4
|
|
Packit |
c4476c |
# rsa 2048 bits 0.003282s 0.000106s 304.7 9438.3
|
|
Packit |
c4476c |
# rsa 4096 bits 0.025866s 0.000340s 38.7 2940.9
|
|
Packit |
c4476c |
# dsa 1024 bits 0.000301s 0.000332s 3323.7 3013.9
|
|
Packit |
c4476c |
# dsa 2048 bits 0.001056s 0.001233s 946.9 810.8
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# 64-bit process, this module:
|
|
Packit |
c4476c |
# sign verify sign/s verify/s
|
|
Packit |
c4476c |
# rsa 1024 bits 0.000256s 0.000016s 3904.4 61411.9
|
|
Packit |
c4476c |
# rsa 2048 bits 0.000946s 0.000029s 1056.8 34292.7
|
|
Packit |
c4476c |
# rsa 4096 bits 0.005061s 0.000340s 197.6 2940.5
|
|
Packit |
c4476c |
# dsa 1024 bits 0.000176s 0.000195s 5674.7 5130.5
|
|
Packit |
c4476c |
# dsa 2048 bits 0.000296s 0.000354s 3383.2 2827.6
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
######################################################################
|
|
Packit |
c4476c |
# 32-bit process, VIS3:
|
|
Packit |
c4476c |
# sign verify sign/s verify/s
|
|
Packit |
c4476c |
# rsa 1024 bits 0.000665s 0.000028s 1504.8 35233.3
|
|
Packit |
c4476c |
# rsa 2048 bits 0.003349s 0.000106s 298.6 9433.4
|
|
Packit |
c4476c |
# rsa 4096 bits 0.025959s 0.000341s 38.5 2934.8
|
|
Packit |
c4476c |
# dsa 1024 bits 0.000320s 0.000341s 3123.3 2929.6
|
|
Packit |
c4476c |
# dsa 2048 bits 0.001101s 0.001260s 908.2 793.4
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# 32-bit process, this module:
|
|
Packit |
c4476c |
# sign verify sign/s verify/s
|
|
Packit |
c4476c |
# rsa 1024 bits 0.000301s 0.000017s 3317.1 60240.0
|
|
Packit |
c4476c |
# rsa 2048 bits 0.001034s 0.000030s 966.9 33812.7
|
|
Packit |
c4476c |
# rsa 4096 bits 0.005244s 0.000341s 190.7 2935.4
|
|
Packit |
c4476c |
# dsa 1024 bits 0.000201s 0.000205s 4976.1 4879.2
|
|
Packit |
c4476c |
# dsa 2048 bits 0.000328s 0.000360s 3051.1 2774.2
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# 32-bit code is prone to performance degradation as interrupt rate
|
|
Packit |
c4476c |
# dispatched to CPU executing the code grows. This is because in
|
|
Packit |
c4476c |
# standard process of handling interrupt in 32-bit process context
|
|
Packit |
c4476c |
# upper halves of most integer registers used as input or output are
|
|
Packit |
c4476c |
# zeroed. This renders result invalid, and operation has to be re-run.
|
|
Packit |
c4476c |
# If CPU is "bothered" with timer interrupts only, the penalty is
|
|
Packit |
c4476c |
# hardly measurable. But in order to mitigate this problem for higher
|
|
Packit |
c4476c |
# interrupt rates contemporary Linux kernel recognizes biased stack
|
|
Packit |
c4476c |
# even in 32-bit process context and preserves full register contents.
|
|
Packit |
c4476c |
# See http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=517ffce4e1a03aea979fe3a18a3dd1761a24fafb
|
|
Packit |
c4476c |
# for details.
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
|
|
Packit |
c4476c |
push(@INC,"${dir}","${dir}../../perlasm");
|
|
Packit |
c4476c |
require "sparcv9_modes.pl";
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$output = pop;
|
|
Packit |
c4476c |
open STDOUT,">$output";
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
#include "sparc_arch.h"
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
.register %g2,#scratch
|
|
Packit |
c4476c |
.register %g3,#scratch
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.section ".text",#alloc,#execinstr
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
#ifdef __PIC__
|
|
Packit |
c4476c |
SPARC_PIC_THUNK(%g1)
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
########################################################################
|
|
Packit |
c4476c |
# Register layout for mont[mul|sqr] instructions.
|
|
Packit |
c4476c |
# For details see "Oracle SPARC Architecture 2011" manual at
|
|
Packit |
c4476c |
# http://www.oracle.com/technetwork/server-storage/sun-sparc-enterprise/documentation/.
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
my @R=map("%f".2*$_,(0..11,30,31,12..29));
|
|
Packit |
c4476c |
my @N=(map("%l$_",(0..7)),map("%o$_",(0..5))); @N=(@N,@N,@N[0..3]);
|
|
Packit |
c4476c |
my @A=(@N[0..13],@R[14..31]);
|
|
Packit |
c4476c |
my @B=(map("%i$_",(0..5)),map("%l$_",(0..7))); @B=(@B,@B,map("%o$_",(0..3)));
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
########################################################################
|
|
Packit |
c4476c |
# int bn_mul_mont_t4_$NUM(u64 *rp,const u64 *ap,const u64 *bp,
|
|
Packit |
c4476c |
# const u64 *np,const BN_ULONG *n0);
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
sub generate_bn_mul_mont_t4() {
|
|
Packit |
c4476c |
my $NUM=shift;
|
|
Packit |
c4476c |
my ($rp,$ap,$bp,$np,$sentinel)=map("%g$_",(1..5));
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.globl bn_mul_mont_t4_$NUM
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_mul_mont_t4_$NUM:
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
mov 0,$sentinel
|
|
Packit |
c4476c |
mov -128,%g4
|
|
Packit |
c4476c |
#elif defined(SPARCV9_64BIT_STACK)
|
|
Packit |
c4476c |
SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
|
|
Packit |
c4476c |
ld [%g1+0],%g1 ! OPENSSL_sparcv9_P[0]
|
|
Packit |
c4476c |
mov -2047,%g4
|
|
Packit |
c4476c |
and %g1,SPARCV9_64BIT_STACK,%g1
|
|
Packit |
c4476c |
movrz %g1,0,%g4
|
|
Packit |
c4476c |
mov -1,$sentinel
|
|
Packit |
c4476c |
add %g4,-128,%g4
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
mov -1,$sentinel
|
|
Packit |
c4476c |
mov -128,%g4
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
sllx $sentinel,32,$sentinel
|
|
Packit |
c4476c |
save %sp,%g4,%sp
|
|
Packit |
c4476c |
#ifndef __arch64__
|
|
Packit |
c4476c |
save %sp,-128,%sp ! warm it up
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
and %sp,1,%g4
|
|
Packit |
c4476c |
or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
or %g4,$sentinel,$sentinel
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
! copy arguments to global registers
|
|
Packit |
c4476c |
mov %i0,$rp
|
|
Packit |
c4476c |
mov %i1,$ap
|
|
Packit |
c4476c |
mov %i2,$bp
|
|
Packit |
c4476c |
mov %i3,$np
|
|
Packit |
c4476c |
ld [%i4+0],%f1 ! load *n0
|
|
Packit |
c4476c |
ld [%i4+4],%f0
|
|
Packit |
c4476c |
fsrc2 %f0,%f60
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# load ap[$NUM] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=$i<13?@A[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$ap+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$ap+$i*8+4],@A[$i]
|
|
Packit |
c4476c |
sllx @A[$i],32,@A[$i]
|
|
Packit |
c4476c |
or $lo,@A[$i],@A[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$ap+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$ap+$i*8+4],$hi
|
|
Packit |
c4476c |
fsrc2 $hi,@A[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
# load np[$NUM] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=$i<13?@N[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$np+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$np+$i*8+4],@N[$i]
|
|
Packit |
c4476c |
sllx @N[$i],32,@N[$i]
|
|
Packit |
c4476c |
or $lo,@N[$i],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<28 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=$i<27?@N[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$np+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$np+$i*8+4],@N[$i]
|
|
Packit |
c4476c |
sllx @N[$i],32,@N[$i]
|
|
Packit |
c4476c |
or $lo,@N[$i],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=($i<$NUM-1)?@N[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$np+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$np+$i*8+4],@N[$i]
|
|
Packit |
c4476c |
sllx @N[$i],32,@N[$i]
|
|
Packit |
c4476c |
or $lo,@N[$i],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
cmp $ap,$bp
|
|
Packit |
c4476c |
be SIZE_T_CC,.Lmsquare_$NUM
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# load bp[$NUM] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=$i<13?@B[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$bp+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$bp+$i*8+4],@B[$i]
|
|
Packit |
c4476c |
sllx @B[$i],32,@B[$i]
|
|
Packit |
c4476c |
or $lo,@B[$i],@B[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my $lo=($i<$NUM-1)?@B[$i+1]:"%o7";
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$bp+$i*8+0],$lo
|
|
Packit |
c4476c |
ld [$bp+$i*8+4],@B[$i]
|
|
Packit |
c4476c |
sllx @B[$i],32,@B[$i]
|
|
Packit |
c4476c |
or $lo,@B[$i],@B[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
# magic ################################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.word 0x81b02920+$NUM-1 ! montmul $NUM-1
|
|
Packit |
c4476c |
.Lmresume_$NUM:
|
|
Packit |
c4476c |
fbu,pn %fcc3,.Lmabort_$NUM
|
|
Packit |
c4476c |
#ifndef __arch64__
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,pn $sentinel,.Lmabort_$NUM
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,pn $sentinel,.Lmabort1_$NUM
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# save tp[$NUM] ########################################################
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
movxtod @A[$i],@R[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
and $sentinel,1,%o7
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
srl %fp,0,%fp ! just in case?
|
|
Packit |
c4476c |
or %o7,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,a,pn $sentinel,.Lmdone_$NUM
|
|
Packit |
c4476c |
mov 0,%i0 ! return failure
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<12 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
@R[$i] =~ /%f([0-9]+)/;
|
|
Packit |
c4476c |
my $lo = "%f".($1+1);
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
st $lo,[$rp+$i*8+0]
|
|
Packit |
c4476c |
st @R[$i],[$rp+$i*8+4]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
fsrc2 @R[$i],$hi
|
|
Packit |
c4476c |
st $lo,[$rp+$i*8+0]
|
|
Packit |
c4476c |
st $hi,[$rp+$i*8+4]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
mov 1,%i0 ! return success
|
|
Packit |
c4476c |
.Lmdone_$NUM:
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.Lmabort_$NUM:
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
.Lmabort1_$NUM:
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mov 0,%i0 ! return failure
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
.Lmsquare_$NUM:
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
.word 0x81b02940+$NUM-1 ! montsqr $NUM-1
|
|
Packit |
c4476c |
ba .Lmresume_$NUM
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
.type bn_mul_mont_t4_$NUM, #function
|
|
Packit |
c4476c |
.size bn_mul_mont_t4_$NUM, .-bn_mul_mont_t4_$NUM
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
for ($i=8;$i<=32;$i+=8) {
|
|
Packit |
c4476c |
&generate_bn_mul_mont_t4($i);
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
########################################################################
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
sub load_ccr {
|
|
Packit |
c4476c |
my ($ptbl,$pwr,$ccr,$skip_wr)=@_;
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
srl $pwr, 2, %o4
|
|
Packit |
c4476c |
and $pwr, 3, %o5
|
|
Packit |
c4476c |
and %o4, 7, %o4
|
|
Packit |
c4476c |
sll %o5, 3, %o5 ! offset within first cache line
|
|
Packit |
c4476c |
add %o5, $ptbl, $ptbl ! of the pwrtbl
|
|
Packit |
c4476c |
or %g0, 1, %o5
|
|
Packit |
c4476c |
sll %o5, %o4, $ccr
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
$code.=<<___ if (!$skip_wr);
|
|
Packit |
c4476c |
wr $ccr, %g0, %ccr
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
sub load_b_pair {
|
|
Packit |
c4476c |
my ($pwrtbl,$B0,$B1)=@_;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$pwrtbl+0*32], $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+8*32], $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+1*32], %o4
|
|
Packit |
c4476c |
ldx [$pwrtbl+9*32], %o5
|
|
Packit |
c4476c |
movvs %icc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+2*32], %o4
|
|
Packit |
c4476c |
movvs %icc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+10*32],%o5
|
|
Packit |
c4476c |
move %icc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+3*32], %o4
|
|
Packit |
c4476c |
move %icc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+11*32],%o5
|
|
Packit |
c4476c |
movneg %icc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+4*32], %o4
|
|
Packit |
c4476c |
movneg %icc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+12*32],%o5
|
|
Packit |
c4476c |
movcs %xcc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+5*32],%o4
|
|
Packit |
c4476c |
movcs %xcc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+13*32],%o5
|
|
Packit |
c4476c |
movvs %xcc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+6*32], %o4
|
|
Packit |
c4476c |
movvs %xcc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+14*32],%o5
|
|
Packit |
c4476c |
move %xcc, %o4, $B0
|
|
Packit |
c4476c |
ldx [$pwrtbl+7*32], %o4
|
|
Packit |
c4476c |
move %xcc, %o5, $B1
|
|
Packit |
c4476c |
ldx [$pwrtbl+15*32],%o5
|
|
Packit |
c4476c |
movneg %xcc, %o4, $B0
|
|
Packit |
c4476c |
add $pwrtbl,16*32, $pwrtbl
|
|
Packit |
c4476c |
movneg %xcc, %o5, $B1
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
sub load_b {
|
|
Packit |
c4476c |
my ($pwrtbl,$Bi)=@_;
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$pwrtbl+0*32], $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+1*32], %o4
|
|
Packit |
c4476c |
ldx [$pwrtbl+2*32], %o5
|
|
Packit |
c4476c |
movvs %icc, %o4, $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+3*32], %o4
|
|
Packit |
c4476c |
move %icc, %o5, $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+4*32], %o5
|
|
Packit |
c4476c |
movneg %icc, %o4, $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+5*32], %o4
|
|
Packit |
c4476c |
movcs %xcc, %o5, $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+6*32], %o5
|
|
Packit |
c4476c |
movvs %xcc, %o4, $Bi
|
|
Packit |
c4476c |
ldx [$pwrtbl+7*32], %o4
|
|
Packit |
c4476c |
move %xcc, %o5, $Bi
|
|
Packit |
c4476c |
add $pwrtbl,8*32, $pwrtbl
|
|
Packit |
c4476c |
movneg %xcc, %o4, $Bi
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
########################################################################
|
|
Packit |
c4476c |
# int bn_pwr5_mont_t4_$NUM(u64 *tp,const u64 *np,const BN_ULONG *n0,
|
|
Packit |
c4476c |
# const u64 *pwrtbl,int pwr,int stride);
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
sub generate_bn_pwr5_mont_t4() {
|
|
Packit |
c4476c |
my $NUM=shift;
|
|
Packit |
c4476c |
my ($tp,$np,$pwrtbl,$pwr,$sentinel)=map("%g$_",(1..5));
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.globl bn_pwr5_mont_t4_$NUM
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_pwr5_mont_t4_$NUM:
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
mov 0,$sentinel
|
|
Packit |
c4476c |
mov -128,%g4
|
|
Packit |
c4476c |
#elif defined(SPARCV9_64BIT_STACK)
|
|
Packit |
c4476c |
SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
|
|
Packit |
c4476c |
ld [%g1+0],%g1 ! OPENSSL_sparcv9_P[0]
|
|
Packit |
c4476c |
mov -2047,%g4
|
|
Packit |
c4476c |
and %g1,SPARCV9_64BIT_STACK,%g1
|
|
Packit |
c4476c |
movrz %g1,0,%g4
|
|
Packit |
c4476c |
mov -1,$sentinel
|
|
Packit |
c4476c |
add %g4,-128,%g4
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
mov -1,$sentinel
|
|
Packit |
c4476c |
mov -128,%g4
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
sllx $sentinel,32,$sentinel
|
|
Packit |
c4476c |
save %sp,%g4,%sp
|
|
Packit |
c4476c |
#ifndef __arch64__
|
|
Packit |
c4476c |
save %sp,-128,%sp ! warm it up
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
save %sp,-128,%sp
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
and %sp,1,%g4
|
|
Packit |
c4476c |
or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
or %g4,$sentinel,$sentinel
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
! copy arguments to global registers
|
|
Packit |
c4476c |
mov %i0,$tp
|
|
Packit |
c4476c |
mov %i1,$np
|
|
Packit |
c4476c |
ld [%i2+0],%f1 ! load *n0
|
|
Packit |
c4476c |
ld [%i2+4],%f0
|
|
Packit |
c4476c |
mov %i3,$pwrtbl
|
|
Packit |
c4476c |
srl %i4,%g0,%i4 ! pack last arguments
|
|
Packit |
c4476c |
sllx %i5,32,$pwr
|
|
Packit |
c4476c |
or %i4,$pwr,$pwr
|
|
Packit |
c4476c |
fsrc2 %f0,%f60
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# load tp[$NUM] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$tp+$i*8],@A[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldd [$tp+$i*8],@A[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
# load np[$NUM] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$np+$i*8],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<28 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$np+$i*8],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ldx [$np+$i*8],@N[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
# load pwrtbl[pwr] ########################################################
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
srlx $pwr, 32, %o4 ! unpack $pwr
|
|
Packit |
c4476c |
srl $pwr, %g0, %o5
|
|
Packit |
c4476c |
sub %o4, 5, %o4
|
|
Packit |
c4476c |
mov $pwrtbl, %o7
|
|
Packit |
c4476c |
sllx %o4, 32, $pwr ! re-pack $pwr
|
|
Packit |
c4476c |
or %o5, $pwr, $pwr
|
|
Packit |
c4476c |
srl %o5, %o4, %o5
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
&load_ccr("%o7","%o5","%o4");
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
b .Lstride_$NUM
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Lstride_$NUM:
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i+=2) {
|
|
Packit |
c4476c |
&load_b_pair("%o7",@B[$i],@B[$i+1]);
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
save %sp,-128,%sp; or $sentinel,%fp,%fp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for(; $i<$NUM; $i+=2) {
|
|
Packit |
c4476c |
&load_b_pair("%i7",@B[$i],@B[$i+1]);
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
srax $pwr, 32, %o4 ! unpack $pwr
|
|
Packit |
c4476c |
srl $pwr, %g0, %o5
|
|
Packit |
c4476c |
sub %o4, 5, %o4
|
|
Packit |
c4476c |
mov $pwrtbl, %i7
|
|
Packit |
c4476c |
sllx %o4, 32, $pwr ! re-pack $pwr
|
|
Packit |
c4476c |
or %o5, $pwr, $pwr
|
|
Packit |
c4476c |
srl %o5, %o4, %o5
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
&load_ccr("%i7","%o5","%o4",1);
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# magic ################################################################
|
|
Packit |
c4476c |
for($i=0; $i<5; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.word 0x81b02940+$NUM-1 ! montsqr $NUM-1
|
|
Packit |
c4476c |
fbu,pn %fcc3,.Labort_$NUM
|
|
Packit |
c4476c |
#ifndef __arch64__
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,pn $sentinel,.Labort_$NUM
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
wr %o4, %g0, %ccr
|
|
Packit |
c4476c |
.word 0x81b02920+$NUM-1 ! montmul $NUM-1
|
|
Packit |
c4476c |
fbu,pn %fcc3,.Labort_$NUM
|
|
Packit |
c4476c |
#ifndef __arch64__
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,pn $sentinel,.Labort_$NUM
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
srax $pwr, 32, %o4
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
brgez %o4,.Lstride_$NUM
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
brgez %o4,.Lstride_$NUM
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore; and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,pn $sentinel,.Labort1_$NUM
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# save tp[$NUM] ########################################################
|
|
Packit |
c4476c |
for($i=0; $i<14 && $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
movxtod @A[$i],@R[$i]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
#ifdef __arch64__
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
#else
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
and $sentinel,1,%o7
|
|
Packit |
c4476c |
and %fp,$sentinel,$sentinel
|
|
Packit |
c4476c |
srl %fp,0,%fp ! just in case?
|
|
Packit |
c4476c |
or %o7,$sentinel,$sentinel
|
|
Packit |
c4476c |
brz,a,pn $sentinel,.Ldone_$NUM
|
|
Packit |
c4476c |
mov 0,%i0 ! return failure
|
|
Packit |
c4476c |
#endif
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
for($i=0; $i<$NUM; $i++) {
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
std @R[$i],[$tp+$i*8]
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
mov 1,%i0 ! return success
|
|
Packit |
c4476c |
.Ldone_$NUM:
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.Labort_$NUM:
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
.Labort1_$NUM:
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mov 0,%i0 ! return failure
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
.type bn_pwr5_mont_t4_$NUM, #function
|
|
Packit |
c4476c |
.size bn_pwr5_mont_t4_$NUM, .-bn_pwr5_mont_t4_$NUM
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
for ($i=8;$i<=32;$i+=8) {
|
|
Packit |
c4476c |
&generate_bn_pwr5_mont_t4($i);
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
{
|
|
Packit |
c4476c |
########################################################################
|
|
Packit |
c4476c |
# Fall-back subroutines
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
# copy of bn_mul_mont_vis3 adjusted for vectors of 64-bit values
|
|
Packit |
c4476c |
#
|
|
Packit |
c4476c |
($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
|
|
Packit |
c4476c |
(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# int bn_mul_mont(
|
|
Packit |
c4476c |
$rp="%o0"; # u64 *rp,
|
|
Packit |
c4476c |
$ap="%o1"; # const u64 *ap,
|
|
Packit |
c4476c |
$bp="%o2"; # const u64 *bp,
|
|
Packit |
c4476c |
$np="%o3"; # const u64 *np,
|
|
Packit |
c4476c |
$n0p="%o4"; # const BN_ULONG *n0,
|
|
Packit |
c4476c |
$num="%o5"; # int num); # caller ensures that num is >=3
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.globl bn_mul_mont_t4
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_mul_mont_t4:
|
|
Packit |
c4476c |
add %sp, STACK_BIAS, %g4 ! real top of stack
|
|
Packit |
c4476c |
sll $num, 3, $num ! size in bytes
|
|
Packit |
c4476c |
add $num, 63, %g1
|
|
Packit |
c4476c |
andn %g1, 63, %g1 ! buffer size rounded up to 64 bytes
|
|
Packit |
c4476c |
sub %g4, %g1, %g1
|
|
Packit |
c4476c |
andn %g1, 63, %g1 ! align at 64 byte
|
|
Packit |
c4476c |
sub %g1, STACK_FRAME, %g1 ! new top of stack
|
|
Packit |
c4476c |
sub %g1, %g4, %g1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
save %sp, %g1, %sp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
# +-------------------------------+<----- %sp
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# +-------------------------------+<----- aligned at 64 bytes
|
|
Packit |
c4476c |
# | __int64 tmp[0] |
|
|
Packit |
c4476c |
# +-------------------------------+
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# +-------------------------------+<----- aligned at 64 bytes
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
|
|
Packit |
c4476c |
($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz)=map("%l$_",(0..7));
|
|
Packit |
c4476c |
($ovf,$i)=($t0,$t1);
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$n0p+0], $t0 ! pull n0[0..1] value
|
|
Packit |
c4476c |
ld [$n0p+4], $t1
|
|
Packit |
c4476c |
add %sp, STACK_BIAS+STACK_FRAME, $tp
|
|
Packit |
c4476c |
ldx [$bp+0], $m0 ! m0=bp[0]
|
|
Packit |
c4476c |
sllx $t1, 32, $n0
|
|
Packit |
c4476c |
add $bp, 8, $bp
|
|
Packit |
c4476c |
or $t0, $n0, $n0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $lo0 ! ap[0]*bp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+8], $aj ! ap[1]
|
|
Packit |
c4476c |
add $ap, 16, $ap
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $lo0, $n0, $m1 ! "tp[0]"*n0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[1]*bp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $lo1 ! np[0]*m1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $hi1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$np+8], $nj ! np[1]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1
|
|
Packit |
c4476c |
add $np, 16, $np
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[1]*m1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .L1st
|
|
Packit |
c4476c |
sub $num, 24, $cnt ! cnt=num-3
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.L1st:
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[j]
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
add $ap, 8, $ap
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[j]
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[j]*bp[0]
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[j]*m1
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0]
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stxa $lo1, [$tp]0xe2 ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp ! tp++
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
brnz,pt $cnt, .L1st
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt ! j--
|
|
Packit |
c4476c |
!.L1st
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stxa $lo1, [$tp]0xe2 ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $hi0, $hi1, $hi1
|
|
Packit |
c4476c |
addxc %g0, %g0, $ovf ! upmost overflow bit
|
|
Packit |
c4476c |
stxa $hi1, [$tp]0xe2
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .Louter
|
|
Packit |
c4476c |
sub $num, 16, $i ! i=num-2
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Louter:
|
|
Packit |
c4476c |
ldx [$bp+0], $m0 ! m0=bp[i]
|
|
Packit |
c4476c |
add $bp, 8, $bp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
sub $ap, $num, $ap ! rewind
|
|
Packit |
c4476c |
sub $np, $num, $np
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[0]
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $lo0 ! ap[0]*bp[i]
|
|
Packit |
c4476c |
ldx [$tp], $tj ! tp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $hi0
|
|
Packit |
c4476c |
ldx [$ap+8], $aj ! ap[1]
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[0]*bp[i]+tp[0]
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[1]*bp[i]
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
mulx $lo0, $n0, $m1 ! tp[0]*n0
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
mulx $nj, $m1, $lo1 ! np[0]*m1
|
|
Packit |
c4476c |
add $ap, 16, $ap
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $hi1
|
|
Packit |
c4476c |
ldx [$np+8], $nj ! np[1]
|
|
Packit |
c4476c |
add $np, 16, $np
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[1]*m1
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .Linner
|
|
Packit |
c4476c |
sub $num, 24, $cnt ! cnt=num-3
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Linner:
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
ldx [$tp+8], $tj ! tp[j]
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[j]
|
|
Packit |
c4476c |
add $ap, 8, $ap
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[j]*bp[i]
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[j]
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[j]*m1
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stx $lo1, [$tp] ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
brnz,pt $cnt, .Linner
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
!.Linner
|
|
Packit |
c4476c |
ldx [$tp+8], $tj ! tp[j]
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stx $lo1, [$tp] ! tp[j-1]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
subcc %g0, $ovf, %g0 ! move upmost overflow to CCR.xcc
|
|
Packit |
c4476c |
addxccc $hi1, $hi0, $hi1
|
|
Packit |
c4476c |
addxc %g0, %g0, $ovf
|
|
Packit |
c4476c |
stx $hi1, [$tp+8]
|
|
Packit |
c4476c |
add $tp, 16, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
brnz,pt $i, .Louter
|
|
Packit |
c4476c |
sub $i, 8, $i
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
sub $ap, $num, $ap ! rewind
|
|
Packit |
c4476c |
sub $np, $num, $np
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
ba .Lsub
|
|
Packit |
c4476c |
subcc $num, 8, $cnt ! cnt=num-1 and clear CCR.xcc
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Lsub:
|
|
Packit |
c4476c |
ldx [$tp], $tj
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
ldx [$np+0], $nj
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
subccc $tj, $nj, $t2 ! tp[j]-np[j]
|
|
Packit |
c4476c |
srlx $tj, 32, $tj
|
|
Packit |
c4476c |
srlx $nj, 32, $nj
|
|
Packit |
c4476c |
subccc $tj, $nj, $t3
|
|
Packit |
c4476c |
add $rp, 8, $rp
|
|
Packit |
c4476c |
st $t2, [$rp-4] ! reverse order
|
|
Packit |
c4476c |
st $t3, [$rp-8]
|
|
Packit |
c4476c |
brnz,pt $cnt, .Lsub
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
sub $np, $num, $np ! rewind
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
sub $rp, $num, $rp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
subccc $ovf, %g0, $ovf ! handle upmost overflow bit
|
|
Packit |
c4476c |
ba .Lcopy
|
|
Packit |
c4476c |
sub $num, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Lcopy: ! conditional copy
|
|
Packit |
c4476c |
ldx [$tp], $tj
|
|
Packit |
c4476c |
ldx [$rp+0], $t2
|
|
Packit |
c4476c |
stx %g0, [$tp] ! zap
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
movcs %icc, $tj, $t2
|
|
Packit |
c4476c |
stx $t2, [$rp+0]
|
|
Packit |
c4476c |
add $rp, 8, $rp
|
|
Packit |
c4476c |
brnz $cnt, .Lcopy
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mov 1, %o0
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
.type bn_mul_mont_t4, #function
|
|
Packit |
c4476c |
.size bn_mul_mont_t4, .-bn_mul_mont_t4
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
# int bn_mul_mont_gather5(
|
|
Packit |
c4476c |
$rp="%o0"; # u64 *rp,
|
|
Packit |
c4476c |
$ap="%o1"; # const u64 *ap,
|
|
Packit |
c4476c |
$bp="%o2"; # const u64 *pwrtbl,
|
|
Packit |
c4476c |
$np="%o3"; # const u64 *np,
|
|
Packit |
c4476c |
$n0p="%o4"; # const BN_ULONG *n0,
|
|
Packit |
c4476c |
$num="%o5"; # int num, # caller ensures that num is >=3
|
|
Packit |
c4476c |
# int power);
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.globl bn_mul_mont_gather5_t4
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_mul_mont_gather5_t4:
|
|
Packit |
c4476c |
add %sp, STACK_BIAS, %g4 ! real top of stack
|
|
Packit |
c4476c |
sll $num, 3, $num ! size in bytes
|
|
Packit |
c4476c |
add $num, 63, %g1
|
|
Packit |
c4476c |
andn %g1, 63, %g1 ! buffer size rounded up to 64 bytes
|
|
Packit |
c4476c |
sub %g4, %g1, %g1
|
|
Packit |
c4476c |
andn %g1, 63, %g1 ! align at 64 byte
|
|
Packit |
c4476c |
sub %g1, STACK_FRAME, %g1 ! new top of stack
|
|
Packit |
c4476c |
sub %g1, %g4, %g1
|
|
Packit |
c4476c |
LDPTR [%sp+STACK_7thARG], %g4 ! load power, 7th argument
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
save %sp, %g1, %sp
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
# +-------------------------------+<----- %sp
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# +-------------------------------+<----- aligned at 64 bytes
|
|
Packit |
c4476c |
# | __int64 tmp[0] |
|
|
Packit |
c4476c |
# +-------------------------------+
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
# +-------------------------------+<----- aligned at 64 bytes
|
|
Packit |
c4476c |
# . .
|
|
Packit |
c4476c |
($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
|
|
Packit |
c4476c |
($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$ccr)=map("%l$_",(0..7));
|
|
Packit |
c4476c |
($ovf,$i)=($t0,$t1);
|
|
Packit |
c4476c |
&load_ccr($bp,"%g4",$ccr);
|
|
Packit |
c4476c |
&load_b($bp,$m0,"%o7"); # m0=bp[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
ld [$n0p+0], $t0 ! pull n0[0..1] value
|
|
Packit |
c4476c |
ld [$n0p+4], $t1
|
|
Packit |
c4476c |
add %sp, STACK_BIAS+STACK_FRAME, $tp
|
|
Packit |
c4476c |
sllx $t1, 32, $n0
|
|
Packit |
c4476c |
or $t0, $n0, $n0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $lo0 ! ap[0]*bp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+8], $aj ! ap[1]
|
|
Packit |
c4476c |
add $ap, 16, $ap
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $lo0, $n0, $m1 ! "tp[0]"*n0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[1]*bp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $lo1 ! np[0]*m1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $hi1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$np+8], $nj ! np[1]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1
|
|
Packit |
c4476c |
add $np, 16, $np
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[1]*m1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .L1st_g5
|
|
Packit |
c4476c |
sub $num, 24, $cnt ! cnt=num-3
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.L1st_g5:
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[j]
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
add $ap, 8, $ap
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[j]
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[j]*bp[0]
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[j]*m1
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0]
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stxa $lo1, [$tp]0xe2 ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp ! tp++
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
brnz,pt $cnt, .L1st_g5
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt ! j--
|
|
Packit |
c4476c |
!.L1st_g5
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1
|
|
Packit |
c4476c |
addcc $lo0, $lo1, $lo1 ! np[j]*m1+ap[j]*bp[0]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stxa $lo1, [$tp]0xe2 ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $hi0, $hi1, $hi1
|
|
Packit |
c4476c |
addxc %g0, %g0, $ovf ! upmost overflow bit
|
|
Packit |
c4476c |
stxa $hi1, [$tp]0xe2
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .Louter_g5
|
|
Packit |
c4476c |
sub $num, 16, $i ! i=num-2
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Louter_g5:
|
|
Packit |
c4476c |
wr $ccr, %g0, %ccr
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
&load_b($bp,$m0); # m0=bp[i]
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
sub $ap, $num, $ap ! rewind
|
|
Packit |
c4476c |
sub $np, $num, $np
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[0]
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[0]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mulx $aj, $m0, $lo0 ! ap[0]*bp[i]
|
|
Packit |
c4476c |
ldx [$tp], $tj ! tp[0]
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $hi0
|
|
Packit |
c4476c |
ldx [$ap+8], $aj ! ap[1]
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[0]*bp[i]+tp[0]
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[1]*bp[i]
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
mulx $lo0, $n0, $m1 ! tp[0]*n0
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
mulx $nj, $m1, $lo1 ! np[0]*m1
|
|
Packit |
c4476c |
add $ap, 16, $ap
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $hi1
|
|
Packit |
c4476c |
ldx [$np+8], $nj ! np[1]
|
|
Packit |
c4476c |
add $np, 16, $np
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[1]*m1
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
ba .Linner_g5
|
|
Packit |
c4476c |
sub $num, 24, $cnt ! cnt=num-3
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Linner_g5:
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
ldx [$tp+8], $tj ! tp[j]
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
ldx [$ap+0], $aj ! ap[j]
|
|
Packit |
c4476c |
add $ap, 8, $ap
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
mulx $aj, $m0, $alo ! ap[j]*bp[i]
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
ldx [$np+0], $nj ! np[j]
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
umulxhi $aj, $m0, $aj ! ahi=aj
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
mulx $nj, $m1, $nlo ! np[j]*m1
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
umulxhi $nj, $m1, $nj ! nhi=nj
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stx $lo1, [$tp] ! tp[j-1]
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
brnz,pt $cnt, .Linner_g5
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
!.Linner_g5
|
|
Packit |
c4476c |
ldx [$tp+8], $tj ! tp[j]
|
|
Packit |
c4476c |
addcc $alo, $hi0, $lo0
|
|
Packit |
c4476c |
addxc $aj, %g0, $hi0 ! ahi=aj
|
|
Packit |
c4476c |
addcc $lo0, $tj, $lo0 ! ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi0, $hi0
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
addcc $nlo, $hi1, $lo1
|
|
Packit |
c4476c |
addxc $nj, %g0, $hi1 ! nhi=nj
|
|
Packit |
c4476c |
addcc $lo1, $lo0, $lo1 ! np[j]*m1+ap[j]*bp[i]+tp[j]
|
|
Packit |
c4476c |
addxc %g0, $hi1, $hi1
|
|
Packit |
c4476c |
stx $lo1, [$tp] ! tp[j-1]
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
subcc %g0, $ovf, %g0 ! move upmost overflow to CCR.xcc
|
|
Packit |
c4476c |
addxccc $hi1, $hi0, $hi1
|
|
Packit |
c4476c |
addxc %g0, %g0, $ovf
|
|
Packit |
c4476c |
stx $hi1, [$tp+8]
|
|
Packit |
c4476c |
add $tp, 16, $tp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
brnz,pt $i, .Louter_g5
|
|
Packit |
c4476c |
sub $i, 8, $i
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
sub $ap, $num, $ap ! rewind
|
|
Packit |
c4476c |
sub $np, $num, $np
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
ba .Lsub_g5
|
|
Packit |
c4476c |
subcc $num, 8, $cnt ! cnt=num-1 and clear CCR.xcc
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Lsub_g5:
|
|
Packit |
c4476c |
ldx [$tp], $tj
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
ldx [$np+0], $nj
|
|
Packit |
c4476c |
add $np, 8, $np
|
|
Packit |
c4476c |
subccc $tj, $nj, $t2 ! tp[j]-np[j]
|
|
Packit |
c4476c |
srlx $tj, 32, $tj
|
|
Packit |
c4476c |
srlx $nj, 32, $nj
|
|
Packit |
c4476c |
subccc $tj, $nj, $t3
|
|
Packit |
c4476c |
add $rp, 8, $rp
|
|
Packit |
c4476c |
st $t2, [$rp-4] ! reverse order
|
|
Packit |
c4476c |
st $t3, [$rp-8]
|
|
Packit |
c4476c |
brnz,pt $cnt, .Lsub_g5
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
sub $np, $num, $np ! rewind
|
|
Packit |
c4476c |
sub $tp, $num, $tp
|
|
Packit |
c4476c |
sub $rp, $num, $rp
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
subccc $ovf, %g0, $ovf ! handle upmost overflow bit
|
|
Packit |
c4476c |
ba .Lcopy_g5
|
|
Packit |
c4476c |
sub $num, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.align 16
|
|
Packit |
c4476c |
.Lcopy_g5: ! conditional copy
|
|
Packit |
c4476c |
ldx [$tp], $tj
|
|
Packit |
c4476c |
ldx [$rp+0], $t2
|
|
Packit |
c4476c |
stx %g0, [$tp] ! zap
|
|
Packit |
c4476c |
add $tp, 8, $tp
|
|
Packit |
c4476c |
movcs %icc, $tj, $t2
|
|
Packit |
c4476c |
stx $t2, [$rp+0]
|
|
Packit |
c4476c |
add $rp, 8, $rp
|
|
Packit |
c4476c |
brnz $cnt, .Lcopy_g5
|
|
Packit |
c4476c |
sub $cnt, 8, $cnt
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
mov 1, %o0
|
|
Packit |
c4476c |
ret
|
|
Packit |
c4476c |
restore
|
|
Packit |
c4476c |
.type bn_mul_mont_gather5_t4, #function
|
|
Packit |
c4476c |
.size bn_mul_mont_gather5_t4, .-bn_mul_mont_gather5_t4
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
}
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
.globl bn_flip_t4
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_flip_t4:
|
|
Packit |
c4476c |
.Loop_flip:
|
|
Packit |
c4476c |
ld [%o1+0], %o4
|
|
Packit |
c4476c |
sub %o2, 1, %o2
|
|
Packit |
c4476c |
ld [%o1+4], %o5
|
|
Packit |
c4476c |
add %o1, 8, %o1
|
|
Packit |
c4476c |
st %o5, [%o0+0]
|
|
Packit |
c4476c |
st %o4, [%o0+4]
|
|
Packit |
c4476c |
brnz %o2, .Loop_flip
|
|
Packit |
c4476c |
add %o0, 8, %o0
|
|
Packit |
c4476c |
retl
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
.type bn_flip_t4, #function
|
|
Packit |
c4476c |
.size bn_flip_t4, .-bn_flip_t4
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.globl bn_flip_n_scatter5_t4
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_flip_n_scatter5_t4:
|
|
Packit |
c4476c |
sll %o3, 3, %o3
|
|
Packit |
c4476c |
srl %o1, 1, %o1
|
|
Packit |
c4476c |
add %o3, %o2, %o2 ! &pwrtbl[pwr]
|
|
Packit |
c4476c |
sub %o1, 1, %o1
|
|
Packit |
c4476c |
.Loop_flip_n_scatter5:
|
|
Packit |
c4476c |
ld [%o0+0], %o4 ! inp[i]
|
|
Packit |
c4476c |
ld [%o0+4], %o5
|
|
Packit |
c4476c |
add %o0, 8, %o0
|
|
Packit |
c4476c |
sllx %o5, 32, %o5
|
|
Packit |
c4476c |
or %o4, %o5, %o5
|
|
Packit |
c4476c |
stx %o5, [%o2]
|
|
Packit |
c4476c |
add %o2, 32*8, %o2
|
|
Packit |
c4476c |
brnz %o1, .Loop_flip_n_scatter5
|
|
Packit |
c4476c |
sub %o1, 1, %o1
|
|
Packit |
c4476c |
retl
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
.type bn_flip_n_scatter5_t4, #function
|
|
Packit |
c4476c |
.size bn_flip_n_scatter5_t4, .-bn_flip_n_scatter5_t4
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.globl bn_gather5_t4
|
|
Packit |
c4476c |
.align 32
|
|
Packit |
c4476c |
bn_gather5_t4:
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
&load_ccr("%o2","%o3","%g1");
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
sub %o1, 1, %o1
|
|
Packit |
c4476c |
.Loop_gather5:
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
&load_b("%o2","%g1");
|
|
Packit |
c4476c |
$code.=<<___;
|
|
Packit |
c4476c |
stx %g1, [%o0]
|
|
Packit |
c4476c |
add %o0, 8, %o0
|
|
Packit |
c4476c |
brnz %o1, .Loop_gather5
|
|
Packit |
c4476c |
sub %o1, 1, %o1
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
retl
|
|
Packit |
c4476c |
nop
|
|
Packit |
c4476c |
.type bn_gather5_t4, #function
|
|
Packit |
c4476c |
.size bn_gather5_t4, .-bn_gather5_t4
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
.asciz "Montgomery Multiplication for SPARC T4, David S. Miller, Andy Polyakov"
|
|
Packit |
c4476c |
.align 4
|
|
Packit |
c4476c |
___
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
&emit_assembler();
|
|
Packit |
c4476c |
|
|
Packit |
c4476c |
close STDOUT or die "error closing STDOUT: $!";
|