From 598c78967f26a0275a1f295ce3a96769f9be91bb Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 5 Aug 2013 15:04:05 -0700 Subject: [PATCH] strings: use runtime assembly for IndexByte Fixes #3751 R=golang-dev, khr CC=golang-dev https://golang.org/cl/12483043 --- src/pkg/runtime/asm_386.s | 16 +++++++++++++++- src/pkg/runtime/asm_amd64.s | 27 +++++++++++++++++++++++---- src/pkg/runtime/asm_arm.s | 24 ++++++++++++++++++++++++ src/pkg/strings/strings.go | 10 ---------- src/pkg/strings/strings.s | 5 +++++ src/pkg/strings/strings_decl.go | 8 ++++++++ 6 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 src/pkg/strings/strings.s create mode 100644 src/pkg/strings/strings_decl.go diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s index f6204acdb6..863bcc32f9 100644 --- a/src/pkg/runtime/asm_386.s +++ b/src/pkg/runtime/asm_386.s @@ -504,7 +504,7 @@ TEXT runtime·atomicstore(SB), 7, $0-8 // so actually // void atomicload64(uint64 *res, uint64 volatile *addr); TEXT runtime·atomicload64(SB), 7, $0-8 - MOVL 4(SP), BX + MOVL 4(SP), BX MOVL 8(SP), AX // MOVQ (%EAX), %MM0 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 @@ -1220,6 +1220,20 @@ TEXT bytes·IndexByte(SB),7,$0 MOVL DI, ret+16(FP) RET +TEXT strings·IndexByte(SB),7,$0 + MOVL s+0(FP), SI + MOVL s_len+4(FP), CX + MOVB c+8(FP), AL + MOVL SI, DI + CLD; REPN; SCASB + JZ 3(PC) + MOVL $-1, ret+12(FP) + RET + SUBL SI, DI + SUBL $1, DI + MOVL DI, ret+12(FP) + RET + // input: // SI = a // DI = b diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s index d22c645740..8cb06d91bf 100644 --- a/src/pkg/runtime/asm_amd64.s +++ b/src/pkg/runtime/asm_amd64.s @@ -1224,6 +1224,25 @@ TEXT bytes·IndexByte(SB),7,$0 MOVQ s+0(FP), SI MOVQ s_len+8(FP), BX MOVB c+24(FP), AL + CALL runtime·indexbytebody(SB) + MOVQ AX, ret+32(FP) + RET + +TEXT strings·IndexByte(SB),7,$0 + MOVQ s+0(FP), SI + MOVQ s_len+8(FP), BX + MOVB c+16(FP), AL + CALL runtime·indexbytebody(SB) + MOVQ AX, ret+24(FP) + RET + +// input: +// SI: data +// BX: data len +// AL: byte sought +// output: +// AX +TEXT runtime·indexbytebody(SB),7,$0 MOVQ SI, DI CMPQ BX, $16 @@ -1281,7 +1300,7 @@ condition: JZ success failure: - MOVQ $-1, ret+32(FP) + MOVQ $-1, AX RET // handle for lengths < 16 @@ -1289,7 +1308,7 @@ indexbyte_small: MOVQ BX, CX REPN; SCASB JZ success - MOVQ $-1, ret+32(FP) + MOVQ $-1, AX RET // we've found the chunk containing the byte @@ -1299,13 +1318,13 @@ ssesuccess: BSFW DX, DX SUBQ SI, DI ADDQ DI, DX - MOVQ DX, ret+32(FP) + MOVQ DX, AX RET success: SUBQ SI, DI SUBL $1, DI - MOVQ DI, ret+32(FP) + MOVQ DI, AX RET TEXT bytes·Equal(SB),7,$0-49 diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s index b7c95fed0d..313e7b84f2 100644 --- a/src/pkg/runtime/asm_arm.s +++ b/src/pkg/runtime/asm_arm.s @@ -667,3 +667,27 @@ _notfound: MOVW $-1, R0 MOVW R0, ret+16(FP) RET + +TEXT strings·IndexByte(SB),7,$0 + MOVW s+0(FP), R0 + MOVW s_len+4(FP), R1 + MOVBU c+8(FP), R2 // byte to find + MOVW R0, R4 // store base for later + ADD R0, R1 // end + +_sib_loop: + CMP R0, R1 + B.EQ _sib_notfound + MOVBU.P 1(R0), R3 + CMP R2, R3 + B.NE _sib_loop + + SUB $1, R0 // R0 will be one beyond the position we want + SUB R4, R0 // remove base + MOVW R0, ret+12(FP) + RET + +_sib_notfound: + MOVW $-1, R0 + MOVW R0, ret+12(FP) + RET diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go index c7ec04b071..4d33f1ecd7 100644 --- a/src/pkg/strings/strings.go +++ b/src/pkg/strings/strings.go @@ -160,16 +160,6 @@ func Index(s, sep string) int { return -1 } -// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s. -func IndexByte(s string, c byte) int { - for i := 0; i < len(s); i++ { - if s[i] == c { - return i - } - } - return -1 -} - // LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s. func LastIndex(s, sep string) int { n := len(sep) diff --git a/src/pkg/strings/strings.s b/src/pkg/strings/strings.s new file mode 100644 index 0000000000..55103bae05 --- /dev/null +++ b/src/pkg/strings/strings.s @@ -0,0 +1,5 @@ +// Copyright 2013 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. + +// This file is here just to make the go tool happy. diff --git a/src/pkg/strings/strings_decl.go b/src/pkg/strings/strings_decl.go new file mode 100644 index 0000000000..810a696af2 --- /dev/null +++ b/src/pkg/strings/strings_decl.go @@ -0,0 +1,8 @@ +// Copyright 2013 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 strings + +// IndexByte returns the index of the first instance of c in s, or -1 if c is not present in s. +func IndexByte(s string, c byte) int // ../runtime/asm_$GOARCH.s -- 2.48.1