Andrzej Szeszo
2013-06-04 453bf5a3004107204e1858532a38b3e703e32995
commit | author | age
fb6de2 1 #
MM 2 # This file addds inline T4 instruction support to OpenSSL upstream code.
3 #
4 Index: Configure
5 ===================================================================
6 diff -ru openssl-1.0.1e/Configure openssl-1.0.1e/Configure
7 --- openssl-1.0.1e/Configure 2011-05-24 17:02:24.000000000 -0700
8 +++ openssl-1.0.1e/Configure 2011-07-27 10:48:17.817470000 -0700
9 @@ -135,7 +135,7 @@
10
11  my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
12  my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
13 -my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
14 +my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
15  my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
16  my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
17  my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
18 Index: crypto/sparccpuid.S
19 ===================================================================
20 diff -ru openssl-1.0.1e/crypto/sparccpuid.S openssl-1.0.1e/crypto/sparccpuid.S
21 --- openssl-1.0.1e/crypto/sparccpuid.S 2011-05-24 17:02:24.000000000 -0700
22 +++ openssl-1.0.1e/crypto/sparccpuid.S 2011-07-27 10:48:17.817470000 -0700
23 @@ -251,6 +251,11 @@
24  !    UltraSPARC IIe        7
25  !    UltraSPARC III        7
26  !    UltraSPARC T1        24
27 +!    SPARC T4        65(*)
28 +!
29 +! (*)    result has lesser to do with VIS instruction latencies, rdtick
30 +!    appears that slow, but it does the trick in sense that FP and
31 +!    VIS code paths are still slower than integer-only ones.
32  !
33  ! Numbers for T2 and SPARC64 V-VII are more than welcomed.
34  !
35 @@ -260,6 +265,8 @@
36  .global    _sparcv9_vis1_instrument
37  .align    8
38  _sparcv9_vis1_instrument:
39 +    .word    0x81b00d80    !fxor    %f0,%f0,%f0
40 +    .word    0x85b08d82    !fxor    %f2,%f2,%f2
41      .word    0x91410000    !rd    %tick,%o0
42      .word    0x81b00d80    !fxor    %f0,%f0,%f0
43      .word    0x85b08d82    !fxor    %f2,%f2,%f2
44 @@ -314,6 +321,30 @@
45  .type    _sparcv9_fmadd_probe,#function
46  .size    _sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
47  
48 +.global    _sparcv9_rdcfr
49 +.align    8
50 +_sparcv9_rdcfr:
51 +    retl
52 +    .word    0x91468000    !rd    %asr26,%o0
53 +.type    _sparcv9_rdcfr,#function
54 +.size    _sparcv9_rdcfr,.-_sparcv9_rdcfr
55 +
56 +.global    _sparcv9_vis3_probe
57 +.align    8
58 +_sparcv9_vis3_probe:
59 +    retl
60 +    .word    0x81b022a0    !xmulx    %g0,%g0,%g0
61 +.type    _sparcv9_vis3_probe,#function
62 +.size    _sparcv9_vis3_probe,.-_sparcv9_vis3_probe
63 +
64 +.global    _sparcv9_random
65 +.align    8
66 +_sparcv9_random:
67 +    retl
68 +    .word    0x91b002a0    !random    %o0
69 +.type    _sparcv9_random,#function
70 +.size    _sparcv9_random,.-_sparcv9_vis3_probe
71 +
72  .global    OPENSSL_cleanse
73  .align    32
74  OPENSSL_cleanse:
75
76 Index: crypto/sparcv9cap.c
77 ===================================================================
78 diff -ru openssl-1.0.1e/crypto/sparcv9cap.c openssl-1.0.1e/crypto/sparcv9cap.c
79 --- openssl-1.0.1e/crypto/sparcv9cap.c 2011-05-24 17:02:24.000000000 -0700
80 +++ openssl-1.0.1e/crypto/sparcv9cap.c 2011-07-27 10:48:17.817470000 -0700
c07dce 81 @@ -6,16 +6,15 @@
fb6de2 82  #include <sys/time.h>
MM 83  #include <openssl/bn.h>
84  
85 -#define SPARCV9_TICK_PRIVILEGED    (1<<0)
86 -#define SPARCV9_PREFER_FPU    (1<<1)
87 -#define SPARCV9_VIS1        (1<<2)
88 -#define SPARCV9_VIS2        (1<<3)    /* reserved */
89 -#define SPARCV9_FMADD        (1<<4)    /* reserved for SPARC64 V */
90 +#include "sparc_arch.h"
91  
92 +#if defined(__GNUC__) && defined(__linux)
93 +__attribute__((visibility("hidden")))
c07dce 94 +#endif
MM 95  #ifndef    _BOOT
96 -static int OPENSSL_sparcv9cap_P=SPARCV9_TICK_PRIVILEGED;
fb6de2 97 +unsigned int OPENSSL_sparcv9cap_P[2]={SPARCV9_TICK_PRIVILEGED,0};
c07dce 98  #else
MM 99 -static int OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
100 +unsigned int OPENSSL_sparcv9cap_P[2]={SPARCV9_VIS1,0};
101  #endif
fb6de2 102  
MM 103  int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num)
c07dce 104 @@ -24,7 +23,7 @@
fb6de2 105      int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num);
MM 106  
107      if (num>=8 && !(num&1) &&
108 -        (OPENSSL_sparcv9cap_P&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
109 +        (OPENSSL_sparcv9cap_P[0]&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
110          (SPARCV9_PREFER_FPU|SPARCV9_VIS1))
111          return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
112      else
c07dce 113 @@ -36,11 +35,16 @@
fb6de2 114  unsigned long    _sparcv9_vis1_instrument(void);
MM 115  void        _sparcv9_vis2_probe(void);
116  void        _sparcv9_fmadd_probe(void);
117 +unsigned long    _sparcv9_rdcfr(void);
118 +void        _sparcv9_vis3_probe(void);
119 +unsigned long    _sparcv9_random(void);
120 +size_t         _sparcv9_vis1_instrument_bus(unsigned int *,size_t);
c07dce 121 +size_t        _sparcv9_vis1_instrument_bus2(unsigned int *,size_t,size_t);
fb6de2 122  
c07dce 123  #ifndef _BOOT
fb6de2 124  unsigned long OPENSSL_rdtsc(void)
MM 125      {
126 -    if (OPENSSL_sparcv9cap_P&SPARCV9_TICK_PRIVILEGED)
127 +    if (OPENSSL_sparcv9cap_P[0]&SPARCV9_TICK_PRIVILEGED)
128  #if defined(__sun) && defined(__SVR4)
129          return gethrtime();
130  #else
c07dce 131 @@ -51,6 +55,25 @@
fb6de2 132      }
c07dce 133  #endif
fb6de2 134  
MM 135 +size_t OPENSSL_instrument_bus(unsigned int *out,size_t cnt)
c07dce 136 +    {
fb6de2 137 +    if (OPENSSL_sparcv9cap_P[0]&(SPARCV9_TICK_PRIVILEGED|SPARCV9_BLK) ==
MM 138 +            SPARCV9_BLK)
139 +        return _sparcv9_vis1_instrument_bus(out,cnt);
140 +    else
141 +        return 0;
c07dce 142 +    }
MM 143 +
fb6de2 144 +size_t OPENSSL_instrument_bus2(unsigned int *out,size_t cnt,size_t max)
MM 145 +    {
146 +    if (OPENSSL_sparcv9cap_P[0]&(SPARCV9_TICK_PRIVILEGED|SPARCV9_BLK) ==
147 +            SPARCV9_BLK)
148 +        return _sparcv9_vis1_instrument_bus2(out,cnt,max);
149 +    else
150 +        return 0;
151 +    }
152 +
c07dce 153 +
MM 154  #if defined(_BOOT)
155  /*
156   * Hardcoding sparc capabilities for wanboot.
157 @@ -58,7 +81,7 @@
fb6de2 158   */
c07dce 159  void OPENSSL_cpuid_setup(void)
MM 160      {
161 -    OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
162 +    OPENSSL_sparcv9cap_P[0] = SPARCV9_VIS1;
163      }
164  
165  #elif 0 && defined(__sun) && defined(__SVR4)
166 @@ -85,11 +108,11 @@
fb6de2 167      if (!strcmp (name,"SUNW,UltraSPARC") ||
MM 168          !strncmp(name,"SUNW,UltraSPARC-I",17))  /* covers II,III,IV */
169          {
170 -        OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
171 +        OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU|SPARCV9_VIS1;
172  
173          /* %tick is privileged only on UltraSPARC-I/II, but not IIe */
174          if (name[14]!='\0' && name[17]!='\0' && name[18]!='\0')
175 -            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
176 +            OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
177  
178          return DI_WALK_TERMINATE;
179          }
c07dce 180 @@ -96,7 +119,7 @@
fb6de2 181      /* This is expected to catch remaining UltraSPARCs, such as T1 */
MM 182      else if (!strncmp(name,"SUNW,UltraSPARC",15))
183          {
184 -        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
185 +        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
186  
187          return DI_WALK_TERMINATE;
188          }
c07dce 189 @@ -115,7 +138,7 @@
fb6de2 190  
MM 191      if ((e=getenv("OPENSSL_sparcv9cap")))
192          {
193 -        OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
194 +        OPENSSL_sparcv9cap_P[0]=strtoul(e,NULL,0);
195          return;
196          }
197  
c07dce 198 @@ -123,17 +146,17 @@
fb6de2 199          {
MM 200          if (strcmp(si,"sun4v"))
201              /* FPU is preferred for all CPUs, but US-T1/2 */
202 -            OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
203 +            OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU;
204          }
205  
206      if (sysinfo(SI_ISALIST,si,sizeof(si))>0)
207          {
208          if (strstr(si,"+vis"))
209 -            OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
210 +            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1|SPARCV9_BLK;
211          if (strstr(si,"+vis2"))
212              {
213 -            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
214 -            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
215 +            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
216 +            OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
217              return;
218              }
219          }
c07dce 220 @@ -193,12 +216,14 @@
fb6de2 221   
MM 222      if ((e=getenv("OPENSSL_sparcv9cap")))
223          {
224 -        OPENSSL_sparcv9cap_P=strtoul(e,NULL,0);
225 +        OPENSSL_sparcv9cap_P[0]=strtoul(e,NULL,0);
226 +        if ((e=strchr(e,':')))
227 +            OPENSSL_sparcv9cap_P[1]=strtoul(e+1,NULL,0);
228          return;
229          }
230  
231      /* Initial value, fits UltraSPARC-I&II... */
232 -    OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED;
233 +    OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU|SPARCV9_TICK_PRIVILEGED;
234  
235      sigfillset(&all_masked);
236      sigdelset(&all_masked,SIGILL);
c07dce 237 @@ -221,20 +246,20 @@
fb6de2 238      if (sigsetjmp(common_jmp,1) == 0)
MM 239          {
240          _sparcv9_rdtick();
241 -        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
242 +        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
243          }
244  
245      if (sigsetjmp(common_jmp,1) == 0)
246          {
247          _sparcv9_vis1_probe();
248 -        OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
249 +        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1|SPARCV9_BLK;
250          /* detect UltraSPARC-Tx, see sparccpud.S for details... */
251          if (_sparcv9_vis1_instrument() >= 12)
252 -            OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU);
253 +            OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1|SPARCV9_PREFER_FPU);
254          else
255              {
256              _sparcv9_vis2_probe();
257 -            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
258 +            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
259              }
260          }
261  
c07dce 262 @@ -241,9 +266,37 @@
fb6de2 263      if (sigsetjmp(common_jmp,1) == 0)
MM 264          {
265          _sparcv9_fmadd_probe();
266 -        OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
267 +        OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD;
268          }
269  
270 +    /*
271 +     * VIS3 flag is tested independently from VIS1, unlike VIS2 that is,
272 +     * because VIS3 defines even integer instructions.
273 +     */
274 +    if (sigsetjmp(common_jmp,1) == 0)
275 +        {
276 +        _sparcv9_vis3_probe();
277 +        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
278 +        }
279 +
280 +    if (sigsetjmp(common_jmp,1) == 0)
281 +        {
282 +        (void)_sparcv9_random();
283 +        OPENSSL_sparcv9cap_P[0] |= SPARCV9_RANDOM;
284 +        }
285 +
286 +    /*
287 +     * In wait for better solution _sparcv9_rdcfr is masked by
288 +     * VIS3 flag, because it goes to uninterruptable endless
289 +     * loop on UltraSPARC II running Solaris. Things might be
290 +     * different on Linux...
291 +     */
292 +    if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3) &&
293 +        sigsetjmp(common_jmp,1) == 0)
294 +        {
295 +        OPENSSL_sparcv9cap_P[1] = (unsigned int)_sparcv9_rdcfr();
296 +        }
297 +
298      sigaction(SIGBUS,&bus_oact,NULL);
299      sigaction(SIGILL,&ill_oact,NULL);
300  
301 Index: crypto/md5/Makefile
302 ===================================================================
303 diff -ru openssl-1.0.1e/crypto/md5/Makefile openssl-1.0.1e/crypto/md5/Makefile
304 --- openssl-1.0.1e/crypto/md5/Makefile    2011-05-24 17:02:24.000000000 -0700
305 +++ openssl-1.0.1e/crypto/md5/Makefile    2011-07-27 10:48:17.817470000 -0700
306 @@ -52,6 +52,9 @@
307      $(CC) $(CFLAGS) -E asm/md5-ia64.S | \
308      $(PERL) -ne 's/;\s+/;\n/g; print;' > $@
309  
310 +md5-sparcv9.S:    asm/md5-sparcv9.pl
311 +    $(PERL) asm/md5-sparcv9.pl $@ $(CFLAGS)
312 +
313  files:
314      $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
315  
316 Index: crypto/md5/md5_locl.h
317 ===================================================================
318 diff -ru openssl-1.0.1e/crypto/md5/md5_locl.h openssl-1.0.1e/crypto/md5/md5_locl.h
319 --- openssl-1.0.1e/crypto/md5/md5_locl.h    2011-05-24 17:02:24.000000000 -0700
320 +++ openssl-1.0.1e/crypto/md5/md5_locl.h    2011-07-27 10:48:17.817470000 -0700
321 @@ -71,6 +71,8 @@
322  #  define md5_block_data_order md5_block_asm_data_order
323  # elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
324  #  define md5_block_data_order md5_block_asm_data_order
325 +# elif defined(__sparc) || defined(__sparc__)
326 +#  define md5_block_data_order md5_block_asm_data_order
327  # endif
328  #endif
329
330 Index: crypto/sha/Makefile
331 ===================================================================
332 diff -ru openssl-1.0.1e/crypto/sha/Makefile openssl-1.0.1e/crypto/sha/Makefile
333 --- openssl-1.0.1e/crypto/sha/Makefile    2011-05-24 17:02:24.000000000 -0700
334 +++ openssl-1.0.1e/crypto/sha/Makefile    2011-07-27 10:48:17.817470000 -0700
335 @@ -66,9 +66,9 @@
336  sha1-x86_64.s:    asm/sha1-x86_64.pl;    $(PERL) asm/sha1-x86_64.pl $(PERLASM_SCHEME) > $@
337  sha256-x86_64.s:asm/sha512-x86_64.pl;    $(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
338  sha512-x86_64.s:asm/sha512-x86_64.pl;    $(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
339 -sha1-sparcv9.s:    asm/sha1-sparcv9.pl;    $(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
340 -sha256-sparcv9.s:asm/sha512-sparcv9.pl;    $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
341 -sha512-sparcv9.s:asm/sha512-sparcv9.pl;    $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
342 +sha1-sparcv9.S:    asm/sha1-sparcv9.pl;    $(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
343 +sha256-sparcv9.S:asm/sha512-sparcv9.pl;    $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
344 +sha512-sparcv9.S:asm/sha512-sparcv9.pl;    $(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
345  
346  sha1-ppc.s:    asm/sha1-ppc.pl;    $(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
347  sha256-ppc.s:    asm/sha512-ppc.pl;    $(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
348 Index: crypto/sha/asm/sha1-sparcv9.pl
349 ===================================================================
350 diff -ru openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl
351 --- openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl 2011-05-24 17:02:24.000000000 -0700
352 +++ openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl 2011-07-27 10:48:17.817470000 -0700
353 @@ -5,6 +5,8 @@
354  # project. The module is, however, dual licensed under OpenSSL and
355  # CRYPTOGAMS licenses depending on where you obtain it. For further
356  # details see http://www.openssl.org/~appro/cryptogams/.
357 +#
358 +# Hardware SPARC T4 support by David S. Miller <davem@davemloft.net>.
359  # ====================================================================
360  
361  # Performance improvement is not really impressive on pre-T1 CPU: +8%
362 @@ -18,6 +20,11 @@
363  # ensure scalability on UltraSPARC T1, or rather to avoid decay when
364  # amount of active threads exceeds the number of physical cores.
365  
366 +# SPARC T4 SHA1 hardware achieves 3.72 cycles per byte, which is 3.1x
367 +# faster than software. Multi-process benchmark saturates at 11x
368 +# single-process result on 8-core processor, or ~9GBps per 2.85GHz
369 +# socket.
370 +
371  $bits=32;
372  for (@ARGV)    { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
373  if ($bits==64)    { $bias=2047; $frame=192; }
374 @@ -183,11 +190,93 @@
375  .register    %g3,#scratch
376  ___
377  $code.=<<___;
378 +#include "sparc_arch.h"
379 +
380  .section    ".text",#alloc,#execinstr
381  
382 +#ifdef __PIC__
383 +SPARC_PIC_THUNK(%g1)
384 +#endif
385 +
386  .align    32
387  .globl    sha1_block_data_order
388  sha1_block_data_order:
389 +    SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
390 +    ld    [%g1+4],%g1        ! OPENSSL_sparcv9cap_P[1]
391 +
392 +    andcc    %g1, CFR_SHA1, %g0
393 +    be    .Lsoftware
394 +    nop
395 +
396 +    ld    [%o0 + 0x00], %f0    ! load context
397 +    ld    [%o0 + 0x04], %f1
398 +    ld    [%o0 + 0x08], %f2
399 +    andcc    %o1, 0x7, %g0
400 +    ld    [%o0 + 0x0c], %f3
401 +    bne,pn    %icc, .Lhwunaligned
402 +     ld    [%o0 + 0x10], %f4
403 +
404 +.Lhw_loop:
405 +    ldd    [%o1 + 0x00], %f8
406 +    ldd    [%o1 + 0x08], %f10
407 +    ldd    [%o1 + 0x10], %f12
408 +    ldd    [%o1 + 0x18], %f14
409 +    ldd    [%o1 + 0x20], %f16
410 +    ldd    [%o1 + 0x28], %f18
411 +    ldd    [%o1 + 0x30], %f20
412 +    subcc    %o2, 1, %o2        ! done yet? 
413 +    ldd    [%o1 + 0x38], %f22
414 +    add    %o1, 0x40, %o1
415 +
416 +    .word    0x81b02820        ! SHA1
417 +
418 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhw_loop
419 +    nop
420 +
421 +.Lhwfinish:
422 +    st    %f0, [%o0 + 0x00]    ! store context
423 +    st    %f1, [%o0 + 0x04]
424 +    st    %f2, [%o0 + 0x08]
425 +    st    %f3, [%o0 + 0x0c]
426 +    retl
427 +    st    %f4, [%o0 + 0x10]
428 +
429 +.align    8
430 +.Lhwunaligned:
431 +    alignaddr %o1, %g0, %o1
432 +
433 +    ldd    [%o1 + 0x00], %f10
434 +.Lhwunaligned_loop:
435 +    ldd    [%o1 + 0x08], %f12
436 +    ldd    [%o1 + 0x10], %f14
437 +    ldd    [%o1 + 0x18], %f16
438 +    ldd    [%o1 + 0x20], %f18
439 +    ldd    [%o1 + 0x28], %f20
440 +    ldd    [%o1 + 0x30], %f22
441 +    ldd    [%o1 + 0x38], %f24
442 +    subcc    %o2, 1, %o2        ! done yet?
443 +    ldd    [%o1 + 0x40], %f26
444 +    add    %o1, 0x40, %o1
445 +
446 +    faligndata %f10, %f12, %f8
447 +    faligndata %f12, %f14, %f10
448 +    faligndata %f14, %f16, %f12
449 +    faligndata %f16, %f18, %f14
450 +    faligndata %f18, %f20, %f16
451 +    faligndata %f20, %f22, %f18
452 +    faligndata %f22, %f24, %f20
453 +    faligndata %f24, %f26, %f22
454 +
455 +    .word    0x81b02820        ! SHA1
456 +
457 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
458 +    for    %f26, %f26, %f10    ! %f10=%f26
459 +
460 +    ba    .Lhwfinish
461 +    nop
462 +
463 +.align    16
464 +.Lsoftware:
465      save    %sp,-$frame,%sp
466      sllx    $len,6,$len
467      add    $inp,$len,$len
468 @@ -279,6 +368,62 @@
469  .align    4
470  ___
471  
472 -$code =~ s/\`([^\`]*)\`/eval $1/gem;
473 -print $code;
474 +# Purpose of these subroutines is to explicitly encode VIS instructions,
475 +# so that one can compile the module without having to specify VIS
476 +# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
477 +# Idea is to reserve for option to produce "universal" binary and let
478 +# programmer detect if current CPU is VIS capable at run-time.
479 +sub unvis {
480 +my ($mnemonic,$rs1,$rs2,$rd)=@_;
481 +my $ref,$opf;
482 +my %visopf = (    "faligndata"    => 0x048,
483 +        "for"        => 0x07c    );
484 +
485 +    $ref = "$mnemonic\t$rs1,$rs2,$rd";
486 +
487 +    if ($opf=$visopf{$mnemonic}) {
488 +    foreach ($rs1,$rs2,$rd) {
489 +        return $ref if (!/%f([0-9]{1,2})/);
490 +        $_=$1;
491 +        if ($1>=32) {
492 +        return $ref if ($1&1);
493 +        # re-encode for upper double register addressing
494 +        $_=($1|$1>>5)&31;
495 +        }
496 +    }
497 +
498 +    return    sprintf ".word\t0x%08x !%s",
499 +            0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
500 +            $ref;
501 +    } else {
502 +    return $ref;
503 +    }
504 +}
505 +sub unalignaddr {
506 +my ($mnemonic,$rs1,$rs2,$rd)=@_;
507 +my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
508 +my $ref="$mnemonic\t$rs1,$rs2,$rd";
509 +
510 +    foreach ($rs1,$rs2,$rd) {
511 +    if (/%([goli])([0-7])/)    { $_=$bias{$1}+$2; }
512 +    else            { return $ref; }
513 +    }
514 +    return  sprintf ".word\t0x%08x !%s",
515 +            0x81b00300|$rd<<25|$rs1<<14|$rs2,
516 +            $ref;
517 +}
518 +
519 +foreach (split("\n",$code)) {
520 +    s/\`([^\`]*)\`/eval $1/ge;
521 +
522 +    s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
523 +        &unvis($1,$2,$3,$4)
524 +     /ge;
525 +    s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
526 +        &unalignaddr($1,$2,$3,$4)
527 +     /ge;
528 +
529 +    print $_,"\n";
530 +}
531 +
532  close STDOUT;
533
534 Index: crypto/sha/asm/sha512-sparcv9.pl
535 ===================================================================
536 diff -ru openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl
537 --- openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl 2011-05-24 17:02:24.000000000 -0700
538 +++ openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl 2011-07-27 10:48:17.817470000 -0700
539 @@ -5,6 +5,8 @@
540  # project. The module is, however, dual licensed under OpenSSL and
541  # CRYPTOGAMS licenses depending on where you obtain it. For further
542  # details see http://www.openssl.org/~appro/cryptogams/.
543 +#
544 +# Hardware SPARC T4 support by David S. Miller <davem@davemloft.net>.
545  # ====================================================================
546  
547  # SHA256 performance improvement over compiler generated code varies
548 @@ -41,6 +43,12 @@
549  #    loads are always slower than one 64-bit load. Once again this
550  #    is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
551  #    2x32-bit loads can be as fast as 1x64-bit ones.
552 +#
553 +# SPARC T4 SHA256/512 hardware achieves 3.17/2.01 cycles per byte,
554 +# which is 9.3x/11.1x faster than software. Multi-process benchmark
555 +# saturates at 11.5x single-process result on 8-core processor, or
556 +# ~11/16GBps per 2.85GHz socket.
557 +
558  
559  $bits=32;
560  for (@ARGV)    { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
561 @@ -386,6 +394,8 @@
562  .register    %g3,#scratch
563  ___
564  $code.=<<___;
565 +#include "sparc_arch.h"
566 +
567  .section    ".text",#alloc,#execinstr
568  
569  .align    64
570 @@ -457,8 +467,196 @@
571  }
572  $code.=<<___;
573  .size    K${label},.-K${label}
574 +
575 +#ifdef __PIC__
576 +SPARC_PIC_THUNK(%g1)
577 +#endif
578 +
579  .globl    sha${label}_block_data_order
580 +.align    32
581  sha${label}_block_data_order:
582 +    SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
583 +    ld    [%g1+4],%g1        ! OPENSSL_sparcv9cap_P[1]
584 +
585 +    andcc    %g1, CFR_SHA${label}, %g0
586 +    be    .Lsoftware
587 +    nop
588 +___
589 +$code.=<<___ if ($SZ==8);         # SHA512
590 +    ldd    [%o0 + 0x00], %f0    ! load context
591 +    ldd    [%o0 + 0x08], %f2
592 +    ldd    [%o0 + 0x10], %f4
593 +    ldd    [%o0 + 0x18], %f6
594 +    ldd    [%o0 + 0x20], %f8
595 +    ldd    [%o0 + 0x28], %f10
596 +    andcc    %o1, 0x7, %g0
597 +    ldd    [%o0 + 0x30], %f12
598 +    bne,pn    %icc, .Lhwunaligned
599 +     ldd    [%o0 + 0x38], %f14
600 +
601 +.Lhwaligned_loop:
602 +    ldd    [%o1 + 0x00], %f16
603 +    ldd    [%o1 + 0x08], %f18
604 +    ldd    [%o1 + 0x10], %f20
605 +    ldd    [%o1 + 0x18], %f22
606 +    ldd    [%o1 + 0x20], %f24
607 +    ldd    [%o1 + 0x28], %f26
608 +    ldd    [%o1 + 0x30], %f28
609 +    ldd    [%o1 + 0x38], %f30
610 +    ldd    [%o1 + 0x40], %f32
611 +    ldd    [%o1 + 0x48], %f34
612 +    ldd    [%o1 + 0x50], %f36
613 +    ldd    [%o1 + 0x58], %f38
614 +    ldd    [%o1 + 0x60], %f40
615 +    ldd    [%o1 + 0x68], %f42
616 +    ldd    [%o1 + 0x70], %f44
617 +    subcc    %o2, 1, %o2        ! done yet?
618 +    ldd    [%o1 + 0x78], %f46
619 +    add    %o1, 0x80, %o1
620 +
621 +    .word    0x81b02860        ! SHA512
622 +
623 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwaligned_loop
624 +    nop
625 +
626 +.Lhwfinish:
627 +    std    %f0, [%o0 + 0x00]    ! store context
628 +    std    %f2, [%o0 + 0x08]
629 +    std    %f4, [%o0 + 0x10]
630 +    std    %f6, [%o0 + 0x18]
631 +    std    %f8, [%o0 + 0x20]
632 +    std    %f10, [%o0 + 0x28]
633 +    std    %f12, [%o0 + 0x30]
634 +    retl
635 +     std    %f14, [%o0 + 0x38]
636 +
637 +.align    16
638 +.Lhwunaligned:
639 +    alignaddr %o1, %g0, %o1
640 +
641 +    ldd    [%o1 + 0x00], %f18
642 +.Lhwunaligned_loop:
643 +    ldd    [%o1 + 0x08], %f20
644 +    ldd    [%o1 + 0x10], %f22
645 +    ldd    [%o1 + 0x18], %f24
646 +    ldd    [%o1 + 0x20], %f26
647 +    ldd    [%o1 + 0x28], %f28
648 +    ldd    [%o1 + 0x30], %f30
649 +    ldd    [%o1 + 0x38], %f32
650 +    ldd    [%o1 + 0x40], %f34
651 +    ldd    [%o1 + 0x48], %f36
652 +    ldd    [%o1 + 0x50], %f38
653 +    ldd    [%o1 + 0x58], %f40
654 +    ldd    [%o1 + 0x60], %f42
655 +    ldd    [%o1 + 0x68], %f44
656 +    ldd    [%o1 + 0x70], %f46
657 +    ldd    [%o1 + 0x78], %f48
658 +    subcc    %o2, 1, %o2        ! done yet?
659 +    ldd    [%o1 + 0x80], %f50
660 +    add    %o1, 0x80, %o1
661 +
662 +    faligndata %f18, %f20, %f16
663 +    faligndata %f20, %f22, %f18
664 +    faligndata %f22, %f24, %f20
665 +    faligndata %f24, %f26, %f22
666 +    faligndata %f26, %f28, %f24
667 +    faligndata %f28, %f30, %f26
668 +    faligndata %f30, %f32, %f28
669 +    faligndata %f32, %f34, %f30
670 +    faligndata %f34, %f36, %f32
671 +    faligndata %f36, %f38, %f34
672 +    faligndata %f38, %f40, %f36
673 +    faligndata %f40, %f42, %f38
674 +    faligndata %f42, %f44, %f40
675 +    faligndata %f44, %f46, %f42
676 +    faligndata %f46, %f48, %f44
677 +    faligndata %f48, %f50, %f46
678 +
679 +    .word    0x81b02860        ! SHA512
680 +
681 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
682 +    for    %f50, %f50, %f18    ! %f18=%f50
683 +
684 +    ba    .Lhwfinish
685 +    nop
686 +___
687 +$code.=<<___ if ($SZ==4);         # SHA256
688 +    ld    [%o0 + 0x00], %f0
689 +    ld    [%o0 + 0x04], %f1
690 +    ld    [%o0 + 0x08], %f2
691 +    ld    [%o0 + 0x0c], %f3
692 +    ld    [%o0 + 0x10], %f4
693 +    ld    [%o0 + 0x14], %f5
694 +    andcc    %o1, 0x7, %g0
695 +    ld    [%o0 + 0x18], %f6
696 +    bne,pn    %icc, .Lhwunaligned
697 +     ld    [%o0 + 0x1c], %f7
698 +
699 +.Lhwloop:
700 +    ldd    [%o1 + 0x00], %f8
701 +    ldd    [%o1 + 0x08], %f10
702 +    ldd    [%o1 + 0x10], %f12
703 +    ldd    [%o1 + 0x18], %f14
704 +    ldd    [%o1 + 0x20], %f16
705 +    ldd    [%o1 + 0x28], %f18
706 +    ldd    [%o1 + 0x30], %f20
707 +    subcc    %o2, 1, %o2        ! done yet?
708 +    ldd    [%o1 + 0x38], %f22
709 +    add    %o1, 0x40, %o1
710 +
711 +    .word    0x81b02840        ! SHA256
712 +
713 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwloop
714 +    nop
715 +
716 +.Lhwfinish:
717 +    st    %f0, [%o0 + 0x00]    ! store context
718 +    st    %f1, [%o0 + 0x04]
719 +    st    %f2, [%o0 + 0x08]
720 +    st    %f3, [%o0 + 0x0c]
721 +    st    %f4, [%o0 + 0x10]
722 +    st    %f5, [%o0 + 0x14]
723 +    st    %f6, [%o0 + 0x18]
724 +    retl
725 +     st    %f7, [%o0 + 0x1c]
726 +
727 +.align    8
728 +.Lhwunaligned:
729 +    alignaddr %o1, %g0, %o1
730 +
731 +    ldd    [%o1 + 0x00], %f10
732 +.Lhwunaligned_loop:
733 +    ldd    [%o1 + 0x08], %f12
734 +    ldd    [%o1 + 0x10], %f14
735 +    ldd    [%o1 + 0x18], %f16
736 +    ldd    [%o1 + 0x20], %f18
737 +    ldd    [%o1 + 0x28], %f20
738 +    ldd    [%o1 + 0x30], %f22
739 +    ldd    [%o1 + 0x38], %f24
740 +    subcc    %o2, 1, %o2        ! done yet?
741 +    ldd    [%o1 + 0x40], %f26
742 +    add    %o1, 0x40, %o1
743 +
744 +    faligndata %f10, %f12, %f8
745 +    faligndata %f12, %f14, %f10
746 +    faligndata %f14, %f16, %f12
747 +    faligndata %f16, %f18, %f14
748 +    faligndata %f18, %f20, %f16
749 +    faligndata %f20, %f22, %f18
750 +    faligndata %f22, %f24, %f20
751 +    faligndata %f24, %f26, %f22
752 +
753 +    .word    0x81b02840        ! SHA256
754 +
755 +    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
756 +    for    %f26, %f26, %f10    ! %f10=%f26
757 +
758 +    ba    .Lhwfinish
759 +    nop
760 +___
761 +$code.=<<___;
762 +.align    16
763 +.Lsoftware:
764      save    %sp,`-$frame-$locals`,%sp
765      and    $inp,`$align-1`,$tmp31
766      sllx    $len,`log(16*$SZ)/log(2)`,$len
767 @@ -589,6 +787,62 @@
768  .align    4
769  ___
770  
771 -$code =~ s/\`([^\`]*)\`/eval $1/gem;
772 -print $code;
773 +# Purpose of these subroutines is to explicitly encode VIS instructions,
774 +# so that one can compile the module without having to specify VIS
775 +# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
776 +# Idea is to reserve for option to produce "universal" binary and let
777 +# programmer detect if current CPU is VIS capable at run-time.
778 +sub unvis {
779 +my ($mnemonic,$rs1,$rs2,$rd)=@_;
780 +my $ref,$opf;
781 +my %visopf = (    "faligndata"    => 0x048,
782 +        "for"        => 0x07c    );
783 +
784 +    $ref = "$mnemonic\t$rs1,$rs2,$rd";
785 +
786 +    if ($opf=$visopf{$mnemonic}) {
787 +    foreach ($rs1,$rs2,$rd) {
788 +        return $ref if (!/%f([0-9]{1,2})/);
789 +        $_=$1;
790 +        if ($1>=32) {
791 +        return $ref if ($1&1);
792 +        # re-encode for upper double register addressing
793 +        $_=($1|$1>>5)&31;
794 +        }
795 +    }
796 +
797 +    return    sprintf ".word\t0x%08x !%s",
798 +            0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
799 +            $ref;
800 +    } else {
801 +    return $ref;
802 +    }
803 +}
804 +sub unalignaddr {
805 +my ($mnemonic,$rs1,$rs2,$rd)=@_;
806 +my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
807 +my $ref="$mnemonic\t$rs1,$rs2,$rd";
808 +
809 +    foreach ($rs1,$rs2,$rd) {
810 +    if (/%([goli])([0-7])/)    { $_=$bias{$1}+$2; }
811 +    else            { return $ref; }
812 +    }
813 +    return  sprintf ".word\t0x%08x !%s",
814 +            0x81b00300|$rd<<25|$rs1<<14|$rs2,
815 +            $ref;
816 +}
817 +
818 +foreach (split("\n",$code)) {
819 +    s/\`([^\`]*)\`/eval $1/ge;
820 +
821 +    s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
822 +        &unvis($1,$2,$3,$4)
823 +     /ge;
824 +    s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
825 +        &unalignaddr($1,$2,$3,$4)
826 +     /ge;
827 +
828 +    print $_,"\n";
829 +}
830 +
831  close STDOUT;
832 Index: openssl/apps/speed.c
833 ===================================================================
834 diff -ru openssl-1.0.1e/apps/spped.c openssl-1.0.1e/apps/speed.c
835 --- openssl-1.0.1e/apps/speed.c 2011-05-24 17:02:24.000000000 -0700
836 +++ openssl-1.0.1e/apps/spped.c 2011-07-27 10:48:17.817470000 -0700
837 @@ -1551,7 +1551,7 @@
838              print_message(names[D_MD5],c[D_MD5][j],lengths[j]);
839              Time_F(START);
840              for (count=0,run=1; COND(c[D_MD5][j]); count++)
841 -                EVP_Digest(&(buf[0]),(unsigned long)lengths[j],&(md5[0]),NULL,EVP_get_digestbyname("md5"),NULL);
842 +                MD5(buf,lengths[j],md5);
843              d=Time_F(STOP);
844              print_result(D_MD5,j,count,d);
845              }
846 @@ -1591,7 +1591,7 @@
847              print_message(names[D_SHA1],c[D_SHA1][j],lengths[j]);
848              Time_F(START);
849              for (count=0,run=1; COND(c[D_SHA1][j]); count++)
850 -                EVP_Digest(buf,(unsigned long)lengths[j],&(sha[0]),NULL,EVP_sha1(),NULL);
851 +                SHA1(buf,lengths[j],sha);
852              d=Time_F(STOP);
853              print_result(D_SHA1,j,count,d);
854              }