diff options
Diffstat (limited to 'src/internal/bytealg')
| -rw-r--r-- | src/internal/bytealg/bytealg.go | 4 | ||||
| -rw-r--r-- | src/internal/bytealg/count_generic.go | 2 | ||||
| -rw-r--r-- | src/internal/bytealg/count_native.go | 2 | ||||
| -rw-r--r-- | src/internal/bytealg/count_riscv64.s | 44 | ||||
| -rw-r--r-- | src/internal/bytealg/equal_mips64x.s | 72 | ||||
| -rw-r--r-- | src/internal/bytealg/index_generic.go | 38 |
6 files changed, 118 insertions, 44 deletions
diff --git a/src/internal/bytealg/bytealg.go b/src/internal/bytealg/bytealg.go index 6fd9308369..b30c234436 100644 --- a/src/internal/bytealg/bytealg.go +++ b/src/internal/bytealg/bytealg.go @@ -99,7 +99,7 @@ func HashStrRev(sep string) (uint32, uint32) { } // IndexRabinKarpBytes uses the Rabin-Karp search algorithm to return the index of the -// first occurence of substr in s, or -1 if not present. +// first occurrence of substr in s, or -1 if not present. func IndexRabinKarpBytes(s, sep []byte) int { // Rabin-Karp search hashsep, pow := HashStrBytes(sep) @@ -124,7 +124,7 @@ func IndexRabinKarpBytes(s, sep []byte) int { } // IndexRabinKarp uses the Rabin-Karp search algorithm to return the index of the -// first occurence of substr in s, or -1 if not present. +// first occurrence of substr in s, or -1 if not present. func IndexRabinKarp(s, substr string) int { // Rabin-Karp search hashss, pow := HashStr(substr) diff --git a/src/internal/bytealg/count_generic.go b/src/internal/bytealg/count_generic.go index 7cc1d50312..5575e81ab8 100644 --- a/src/internal/bytealg/count_generic.go +++ b/src/internal/bytealg/count_generic.go @@ -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,!arm,!arm64,!ppc64le,!ppc64,!s390x +// +build !amd64,!arm,!arm64,!ppc64le,!ppc64,!riscv64,!s390x package bytealg diff --git a/src/internal/bytealg/count_native.go b/src/internal/bytealg/count_native.go index 0448fca9e8..b1ff1d265a 100644 --- a/src/internal/bytealg/count_native.go +++ b/src/internal/bytealg/count_native.go @@ -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 arm arm64 ppc64le ppc64 s390x +// +build amd64 arm arm64 ppc64le ppc64 riscv64 s390x package bytealg diff --git a/src/internal/bytealg/count_riscv64.s b/src/internal/bytealg/count_riscv64.s new file mode 100644 index 0000000000..3f4eb23286 --- /dev/null +++ b/src/internal/bytealg/count_riscv64.s @@ -0,0 +1,44 @@ +// Copyright 2020 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 "go_asm.h" +#include "textflag.h" + +TEXT ·Count(SB),NOSPLIT,$0-40 + MOV b_base+0(FP), A1 + MOV b_len+8(FP), A2 + MOVBU c+24(FP), A3 // byte to count + MOV ZERO, A4 // count + ADD A1, A2 // end + +loop: + BEQ A1, A2, done + MOVBU (A1), A5 + ADD $1, A1 + BNE A3, A5, loop + ADD $1, A4 + JMP loop + +done: + MOV A4, ret+32(FP) + RET + +TEXT ·CountString(SB),NOSPLIT,$0-32 + MOV s_base+0(FP), A1 + MOV s_len+8(FP), A2 + MOVBU c+16(FP), A3 // byte to count + MOV ZERO, A4 // count + ADD A1, A2 // end + +loop: + BEQ A1, A2, done + MOVBU (A1), A5 + ADD $1, A1 + BNE A3, A5, loop + ADD $1, A4 + JMP loop + +done: + MOV A4, ret+24(FP) + RET diff --git a/src/internal/bytealg/equal_mips64x.s b/src/internal/bytealg/equal_mips64x.s index 58dc4303b4..641e3ff06c 100644 --- a/src/internal/bytealg/equal_mips64x.s +++ b/src/internal/bytealg/equal_mips64x.s @@ -16,18 +16,82 @@ TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 BEQ R1, R2, eq MOVV size+16(FP), R3 ADDV R1, R3, R4 -loop: - BNE R1, R4, test + + // chunk size is 16 + SGTU $16, R3, R8 + BEQ R0, R8, chunk_entry + +byte_loop: + BNE R1, R4, byte_test MOVV $1, R1 MOVB R1, ret+24(FP) RET -test: +byte_test: MOVBU (R1), R6 ADDV $1, R1 MOVBU (R2), R7 ADDV $1, R2 - BEQ R6, R7, loop + BEQ R6, R7, byte_loop + JMP not_eq + +chunk_entry: + // make sure both a and b are aligned + OR R1, R2, R9 + AND $0x7, R9 + BNE R0, R9, byte_loop + JMP chunk_loop_1 + +chunk_loop: + // chunk size is 16 + SGTU $16, R3, R8 + BNE R0, R8, chunk_tail_8 +chunk_loop_1: + MOVV (R1), R6 + MOVV (R2), R7 + BNE R6, R7, not_eq + MOVV 8(R1), R12 + MOVV 8(R2), R13 + ADDV $16, R1 + ADDV $16, R2 + SUBV $16, R3 + BEQ R12, R13, chunk_loop + JMP not_eq + +chunk_tail_8: + AND $8, R3, R14 + BEQ R0, R14, chunk_tail_4 + MOVV (R1), R6 + MOVV (R2), R7 + BNE R6, R7, not_eq + ADDV $8, R1 + ADDV $8, R2 + +chunk_tail_4: + AND $4, R3, R14 + BEQ R0, R14, chunk_tail_2 + MOVWU (R1), R6 + MOVWU (R2), R7 + BNE R6, R7, not_eq + ADDV $4, R1 + ADDV $4, R2 + +chunk_tail_2: + AND $2, R3, R14 + BEQ R0, R14, chunk_tail_1 + MOVHU (R1), R6 + MOVHU (R2), R7 + BNE R6, R7, not_eq + ADDV $2, R1 + ADDV $2, R2 + +chunk_tail_1: + AND $1, R3, R14 + BEQ R0, R14, eq + MOVBU (R1), R6 + MOVBU (R2), R7 + BEQ R6, R7, eq +not_eq: MOVB R0, ret+24(FP) RET eq: diff --git a/src/internal/bytealg/index_generic.go b/src/internal/bytealg/index_generic.go index 83345f1013..98e859f925 100644 --- a/src/internal/bytealg/index_generic.go +++ b/src/internal/bytealg/index_generic.go @@ -16,42 +16,8 @@ func Index(a, b []byte) int { // IndexString returns the index of the first instance of b in a, or -1 if b is not present in a. // Requires 2 <= len(b) <= MaxLen. -func IndexString(s, substr string) int { - // This is a partial copy of strings.Index, here because bytes.IndexAny and bytes.LastIndexAny - // call bytealg.IndexString. Some platforms have an optimized assembly version of this function. - // This implementation is used for those that do not. Although the pure Go implementation here - // works for the case of len(b) > MaxLen, we do not require that its assembly implementation also - // supports the case of len(b) > MaxLen. And we do not guarantee that this function supports the - // case of len(b) > MaxLen. - n := len(substr) - c0 := substr[0] - c1 := substr[1] - i := 0 - t := len(s) - n + 1 - fails := 0 - for i < t { - if s[i] != c0 { - o := IndexByteString(s[i:t], c0) - if o < 0 { - return -1 - } - i += o - } - if s[i+1] == c1 && s[i:i+n] == substr { - return i - } - i++ - fails++ - if fails >= 4+i>>4 && i < t { - // See comment in src/bytes/bytes.go. - j := IndexRabinKarp(s[i:], substr) - if j < 0 { - return -1 - } - return i + j - } - } - return -1 +func IndexString(a, b string) int { + panic("unimplemented") } // Cutover reports the number of failures of IndexByte we should tolerate |
