1 | #! /usr/bin/env perl
|
---|
2 | # Copyright 2012-2020 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | #
|
---|
4 | # Licensed under the OpenSSL license (the "License"). You may not use
|
---|
5 | # this file except in compliance with the License. You can obtain a copy
|
---|
6 | # in the file LICENSE in the source distribution or at
|
---|
7 | # https://www.openssl.org/source/license.html
|
---|
8 |
|
---|
9 | #
|
---|
10 | # ====================================================================
|
---|
11 | # Written by Andy Polyakov <[email protected]> for the OpenSSL
|
---|
12 | # project. The module is, however, dual licensed under OpenSSL and
|
---|
13 | # CRYPTOGAMS licenses depending on where you obtain it. For further
|
---|
14 | # details see http://www.openssl.org/~appro/cryptogams/.
|
---|
15 | # ====================================================================
|
---|
16 | #
|
---|
17 | # October 2012
|
---|
18 | #
|
---|
19 | # The module implements bn_GF2m_mul_2x2 polynomial multiplication used
|
---|
20 | # in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
|
---|
21 | # the time being... Except that it has two code paths: one suitable
|
---|
22 | # for all SPARCv9 processors and one for VIS3-capable ones. Former
|
---|
23 | # delivers ~25-45% more, more for longer keys, heaviest DH and DSA
|
---|
24 | # verify operations on venerable UltraSPARC II. On T4 VIS3 code is
|
---|
25 | # ~100-230% faster than gcc-generated code and ~35-90% faster than
|
---|
26 | # the pure SPARCv9 code path.
|
---|
27 |
|
---|
28 | $output = pop;
|
---|
29 | open STDOUT,">$output";
|
---|
30 |
|
---|
31 | $locals=16*8;
|
---|
32 |
|
---|
33 | $tab="%l0";
|
---|
34 |
|
---|
35 | @T=("%g2","%g3");
|
---|
36 | @i=("%g4","%g5");
|
---|
37 |
|
---|
38 | ($a1,$a2,$a4,$a8,$a12,$a48)=map("%o$_",(0..5));
|
---|
39 | ($lo,$hi,$b)=("%g1",$a8,"%o7"); $a=$lo;
|
---|
40 |
|
---|
41 | $code.=<<___;
|
---|
42 | #include <sparc_arch.h>
|
---|
43 |
|
---|
44 | #ifdef __arch64__
|
---|
45 | .register %g2,#scratch
|
---|
46 | .register %g3,#scratch
|
---|
47 | #endif
|
---|
48 |
|
---|
49 | #ifdef __PIC__
|
---|
50 | SPARC_PIC_THUNK(%g1)
|
---|
51 | #endif
|
---|
52 |
|
---|
53 | .globl bn_GF2m_mul_2x2
|
---|
54 | .align 16
|
---|
55 | bn_GF2m_mul_2x2:
|
---|
56 | SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
|
---|
57 | ld [%g1+0],%g1 ! OPENSSL_sparcv9cap_P[0]
|
---|
58 |
|
---|
59 | andcc %g1, SPARCV9_VIS3, %g0
|
---|
60 | bz,pn %icc,.Lsoftware
|
---|
61 | nop
|
---|
62 |
|
---|
63 | sllx %o1, 32, %o1
|
---|
64 | sllx %o3, 32, %o3
|
---|
65 | or %o2, %o1, %o1
|
---|
66 | or %o4, %o3, %o3
|
---|
67 | .word 0x95b262ab ! xmulx %o1, %o3, %o2
|
---|
68 | .word 0x99b262cb ! xmulxhi %o1, %o3, %o4
|
---|
69 | srlx %o2, 32, %o1 ! 13 cycles later
|
---|
70 | st %o2, [%o0+0]
|
---|
71 | st %o1, [%o0+4]
|
---|
72 | srlx %o4, 32, %o3
|
---|
73 | st %o4, [%o0+8]
|
---|
74 | retl
|
---|
75 | st %o3, [%o0+12]
|
---|
76 |
|
---|
77 | .align 16
|
---|
78 | .Lsoftware:
|
---|
79 | save %sp,-STACK_FRAME-$locals,%sp
|
---|
80 |
|
---|
81 | sllx %i1,32,$a
|
---|
82 | mov -1,$a12
|
---|
83 | sllx %i3,32,$b
|
---|
84 | or %i2,$a,$a
|
---|
85 | srlx $a12,1,$a48 ! 0x7fff...
|
---|
86 | or %i4,$b,$b
|
---|
87 | srlx $a12,2,$a12 ! 0x3fff...
|
---|
88 | add %sp,STACK_BIAS+STACK_FRAME,$tab
|
---|
89 |
|
---|
90 | sllx $a,2,$a4
|
---|
91 | mov $a,$a1
|
---|
92 | sllx $a,1,$a2
|
---|
93 |
|
---|
94 | srax $a4,63,@i[1] ! broadcast 61st bit
|
---|
95 | and $a48,$a4,$a4 ! (a<<2)&0x7fff...
|
---|
96 | srlx $a48,2,$a48
|
---|
97 | srax $a2,63,@i[0] ! broadcast 62nd bit
|
---|
98 | and $a12,$a2,$a2 ! (a<<1)&0x3fff...
|
---|
99 | srax $a1,63,$lo ! broadcast 63rd bit
|
---|
100 | and $a48,$a1,$a1 ! (a<<0)&0x1fff...
|
---|
101 |
|
---|
102 | sllx $a1,3,$a8
|
---|
103 | and $b,$lo,$lo
|
---|
104 | and $b,@i[0],@i[0]
|
---|
105 | and $b,@i[1],@i[1]
|
---|
106 |
|
---|
107 | stx %g0,[$tab+0*8] ! tab[0]=0
|
---|
108 | xor $a1,$a2,$a12
|
---|
109 | stx $a1,[$tab+1*8] ! tab[1]=a1
|
---|
110 | stx $a2,[$tab+2*8] ! tab[2]=a2
|
---|
111 | xor $a4,$a8,$a48
|
---|
112 | stx $a12,[$tab+3*8] ! tab[3]=a1^a2
|
---|
113 | xor $a4,$a1,$a1
|
---|
114 |
|
---|
115 | stx $a4,[$tab+4*8] ! tab[4]=a4
|
---|
116 | xor $a4,$a2,$a2
|
---|
117 | stx $a1,[$tab+5*8] ! tab[5]=a1^a4
|
---|
118 | xor $a4,$a12,$a12
|
---|
119 | stx $a2,[$tab+6*8] ! tab[6]=a2^a4
|
---|
120 | xor $a48,$a1,$a1
|
---|
121 | stx $a12,[$tab+7*8] ! tab[7]=a1^a2^a4
|
---|
122 | xor $a48,$a2,$a2
|
---|
123 |
|
---|
124 | stx $a8,[$tab+8*8] ! tab[8]=a8
|
---|
125 | xor $a48,$a12,$a12
|
---|
126 | stx $a1,[$tab+9*8] ! tab[9]=a1^a8
|
---|
127 | xor $a4,$a1,$a1
|
---|
128 | stx $a2,[$tab+10*8] ! tab[10]=a2^a8
|
---|
129 | xor $a4,$a2,$a2
|
---|
130 | stx $a12,[$tab+11*8] ! tab[11]=a1^a2^a8
|
---|
131 |
|
---|
132 | xor $a4,$a12,$a12
|
---|
133 | stx $a48,[$tab+12*8] ! tab[12]=a4^a8
|
---|
134 | srlx $lo,1,$hi
|
---|
135 | stx $a1,[$tab+13*8] ! tab[13]=a1^a4^a8
|
---|
136 | sllx $lo,63,$lo
|
---|
137 | stx $a2,[$tab+14*8] ! tab[14]=a2^a4^a8
|
---|
138 | srlx @i[0],2,@T[0]
|
---|
139 | stx $a12,[$tab+15*8] ! tab[15]=a1^a2^a4^a8
|
---|
140 |
|
---|
141 | sllx @i[0],62,$a1
|
---|
142 | sllx $b,3,@i[0]
|
---|
143 | srlx @i[1],3,@T[1]
|
---|
144 | and @i[0],`0xf<<3`,@i[0]
|
---|
145 | sllx @i[1],61,$a2
|
---|
146 | ldx [$tab+@i[0]],@i[0]
|
---|
147 | srlx $b,4-3,@i[1]
|
---|
148 | xor @T[0],$hi,$hi
|
---|
149 | and @i[1],`0xf<<3`,@i[1]
|
---|
150 | xor $a1,$lo,$lo
|
---|
151 | ldx [$tab+@i[1]],@i[1]
|
---|
152 | xor @T[1],$hi,$hi
|
---|
153 |
|
---|
154 | xor @i[0],$lo,$lo
|
---|
155 | srlx $b,8-3,@i[0]
|
---|
156 | xor $a2,$lo,$lo
|
---|
157 | and @i[0],`0xf<<3`,@i[0]
|
---|
158 | ___
|
---|
159 | for($n=1;$n<14;$n++) {
|
---|
160 | $code.=<<___;
|
---|
161 | sllx @i[1],`$n*4`,@T[0]
|
---|
162 | ldx [$tab+@i[0]],@i[0]
|
---|
163 | srlx @i[1],`64-$n*4`,@T[1]
|
---|
164 | xor @T[0],$lo,$lo
|
---|
165 | srlx $b,`($n+2)*4`-3,@i[1]
|
---|
166 | xor @T[1],$hi,$hi
|
---|
167 | and @i[1],`0xf<<3`,@i[1]
|
---|
168 | ___
|
---|
169 | push(@i,shift(@i)); push(@T,shift(@T));
|
---|
170 | }
|
---|
171 | $code.=<<___;
|
---|
172 | sllx @i[1],`$n*4`,@T[0]
|
---|
173 | ldx [$tab+@i[0]],@i[0]
|
---|
174 | srlx @i[1],`64-$n*4`,@T[1]
|
---|
175 | xor @T[0],$lo,$lo
|
---|
176 |
|
---|
177 | sllx @i[0],`($n+1)*4`,@T[0]
|
---|
178 | xor @T[1],$hi,$hi
|
---|
179 | srlx @i[0],`64-($n+1)*4`,@T[1]
|
---|
180 | xor @T[0],$lo,$lo
|
---|
181 | xor @T[1],$hi,$hi
|
---|
182 |
|
---|
183 | srlx $lo,32,%i1
|
---|
184 | st $lo,[%i0+0]
|
---|
185 | st %i1,[%i0+4]
|
---|
186 | srlx $hi,32,%i2
|
---|
187 | st $hi,[%i0+8]
|
---|
188 | st %i2,[%i0+12]
|
---|
189 |
|
---|
190 | ret
|
---|
191 | restore
|
---|
192 | .type bn_GF2m_mul_2x2,#function
|
---|
193 | .size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
|
---|
194 | .asciz "GF(2^m) Multiplication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
|
---|
195 | .align 4
|
---|
196 | ___
|
---|
197 |
|
---|
198 | $code =~ s/\`([^\`]*)\`/eval($1)/gem;
|
---|
199 | print $code;
|
---|
200 | close STDOUT or die "error closing STDOUT: $!";
|
---|