]> Cypherpunks repositories - gostls13.git/commitdiff
strings: use runtime assembly for IndexByte
authorBrad Fitzpatrick <bradfitz@golang.org>
Mon, 5 Aug 2013 22:04:05 +0000 (15:04 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 5 Aug 2013 22:04:05 +0000 (15:04 -0700)
Fixes #3751

R=golang-dev, khr
CC=golang-dev
https://golang.org/cl/12483043

src/pkg/runtime/asm_386.s
src/pkg/runtime/asm_amd64.s
src/pkg/runtime/asm_arm.s
src/pkg/strings/strings.go
src/pkg/strings/strings.s [new file with mode: 0644]
src/pkg/strings/strings_decl.go [new file with mode: 0644]

index f6204acdb6c49bd0299fbec223d3656a09650c98..863bcc32f9c7ec08951e5d57a81b958768628237 100644 (file)
@@ -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
index d22c64574024ac8222b3d9dd47d165f943f403b2..8cb06d91bf97d93595825aeb000858a45cddec94 100644 (file)
@@ -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
index b7c95fed0df706cc3140c75c97ca3ef984ea15a3..313e7b84f2ed0d2b32785918923d907e12313ef6 100644 (file)
@@ -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
index c7ec04b071a5c6c27b3a3396096cf6da540b7bd9..4d33f1ecd7c79acddd06fca133a1a1b6bbf9a69b 100644 (file)
@@ -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 (file)
index 0000000..55103ba
--- /dev/null
@@ -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 (file)
index 0000000..810a696
--- /dev/null
@@ -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