]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/sha1: add s390x assembly implementation
authorMichael Munday <munday@ca.ibm.com>
Mon, 18 Apr 2016 21:41:50 +0000 (17:41 -0400)
committerMichael Munday <munday@ca.ibm.com>
Fri, 22 Apr 2016 05:27:51 +0000 (05:27 +0000)
Use the compute intermediate message digest (KIMD) instruction
when possible. Adds test to check fallback code path in case
KIMD is not available.

Benchmark changes:
Hash8Bytes  3.4x
Hash1K      9.3x
Hash8K      10.9x

Change-Id: Ibcd71a886dfd7b3822042235b4f4eaa7a148036b
Reviewed-on: https://go-review.googlesource.com/22350
Run-TryBot: Michael Munday <munday@ca.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/crypto/sha1/fallback_test.go [new file with mode: 0644]
src/crypto/sha1/sha1_test.go
src/crypto/sha1/sha1block_decl.go
src/crypto/sha1/sha1block_generic.go
src/crypto/sha1/sha1block_s390x.go [new file with mode: 0644]
src/crypto/sha1/sha1block_s390x.s [new file with mode: 0644]

diff --git a/src/crypto/sha1/fallback_test.go b/src/crypto/sha1/fallback_test.go
new file mode 100644 (file)
index 0000000..08acd04
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build s390x
+
+package sha1
+
+import (
+       "fmt"
+       "io"
+       "testing"
+)
+
+// Tests the fallback code path in case the optimized asm
+// implementation cannot be used.
+// See also TestBlockGeneric.
+func TestGenericPath(t *testing.T) {
+       if useAsm == false {
+               t.Skipf("assembly implementation unavailable")
+       }
+       useAsm = false
+       defer func() { useAsm = true }()
+       c := New()
+       in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
+       gold := "0f58c2bb130f8182375f325c18342215255387e5"
+       if _, err := io.WriteString(c, in); err != nil {
+               t.Fatalf("could not write to c: %v", err)
+       }
+       out := fmt.Sprintf("%x", c.Sum(nil))
+       if out != gold {
+               t.Fatalf("mismatch: got %s, wanted %s", out, gold)
+       }
+}
index 80ac5e9f74fbbe114641640665c27f92eda82179..9202e682a8f9b970325d655b7efcc84c7c710a1d 100644 (file)
@@ -91,7 +91,7 @@ func TestBlockSize(t *testing.T) {
        }
 }
 
-// Tests that blockGeneric (pure Go) and block (in assembly for amd64, 386, arm) match.
+// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
 func TestBlockGeneric(t *testing.T) {
        gen, asm := New().(*digest), New().(*digest)
        buf := make([]byte, BlockSize*20) // arbitrary factor
index 082735f06437ce80856974856ca20ba08bf309a8..a85b74b878717419e88cbda37cfdcc34785a0c34 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build amd64 amd64p32 arm 386
+// +build amd64 amd64p32 arm 386 s390x
 
 package sha1
 
index 696e26b6257fdfa411f7bc7fc8dd50cc1f10f604..f0194626a6f24dca6b24f4998ab991767b9e1217 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build !amd64,!amd64p32,!386,!arm
+// +build !amd64,!amd64p32,!386,!arm,!s390x
 
 package sha1
 
diff --git a/src/crypto/sha1/sha1block_s390x.go b/src/crypto/sha1/sha1block_s390x.go
new file mode 100644 (file)
index 0000000..aac7c11
--- /dev/null
@@ -0,0 +1,12 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sha1
+
+// featureCheck reports whether the CPU supports the
+// SHA1 compute intermediate message digest (KIMD)
+// function code.
+func featureCheck() bool
+
+var useAsm = featureCheck()
diff --git a/src/crypto/sha1/sha1block_s390x.s b/src/crypto/sha1/sha1block_s390x.s
new file mode 100644 (file)
index 0000000..a9c4b08
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func featureCheck() bool
+TEXT ·featureCheck(SB),NOSPLIT,$16-1
+       LA      tmp-16(SP), R1
+       XOR     R0, R0         // query function code is 0
+       WORD    $0xB93E0006    // KIMD (R6 is ignored)
+       MOVBZ   tmp-16(SP), R4 // get the first byte
+       AND     $0x40, R4      // bit 1 (big endian) for SHA1
+       CMPBEQ  R4, $0, nosha1
+       MOVB    $1, ret+0(FP)
+       RET
+nosha1:
+       MOVB    $0, ret+0(FP)
+       RET
+
+// func block(dig *digest, p []byte)
+TEXT ·block(SB),NOSPLIT,$0-32
+       MOVBZ   ·useAsm(SB), R4
+       LMG     dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
+       CMPBNE  R4, $1, generic
+       MOVBZ   $1, R0        // SHA1 function code
+loop:
+       WORD    $0xB93E0002   // KIMD R2
+       BVS     loop          // continue if interrupted
+done:
+       XOR     R0, R0        // restore R0
+       RET
+generic:
+       BR      ·blockGeneric(SB)