Commit ad4a58e3 authored by Keith Randall's avatar Keith Randall Committed by Keith Randall

strings,bytes: use inlineable function trampolines instead of linkname

Cleans things up quite a bit.

There's still a few more, like runtime.cmpstring, which might also
be worth fixing.

Change-Id: Ide18dd621efc129cc686db223f47fa0b044b5580
Reviewed-on: https://go-review.googlesource.com/c/148578
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarAustin Clements <austin@google.com>
parent 742be070
......@@ -12,6 +12,13 @@ import (
"unicode/utf8"
)
// Equal returns a boolean reporting whether a and b
// are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice.
func Equal(a, b []byte) bool {
return bytealg.Equal(a, b)
}
func equalPortable(a, b []byte) bool {
if len(a) != len(b) {
return false
......@@ -24,6 +31,13 @@ func equalPortable(a, b []byte) bool {
return true
}
// Compare returns an integer comparing two byte slices lexicographically.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice.
func Compare(a, b []byte) int {
return bytealg.Compare(a, b)
}
// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
func explode(s []byte, n int) [][]byte {
......@@ -83,6 +97,11 @@ func ContainsRune(b []byte, r rune) bool {
return IndexRune(b, r) >= 0
}
// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
func IndexByte(b []byte, c byte) int {
return bytealg.IndexByte(b, c)
}
func indexBytePortable(s []byte, c byte) int {
for i, b := range s {
if b == c {
......
// Copyright 2010 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 bytes
//go:noescape
// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b.
func IndexByte(b []byte, c byte) int // in internal/bytealg
//go:noescape
// Equal returns a boolean reporting whether a and b
// are the same length and contain the same bytes.
// A nil argument is equivalent to an empty slice.
func Equal(a, b []byte) bool // in internal/bytealg
//go:noescape
// Compare returns an integer comparing two byte slices lexicographically.
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice.
func Compare(a, b []byte) int // in internal/bytealg
// 386-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_386.s: [386] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_386.s: [386] cannot check cross-package assembly function: cmpstring is in package runtime
// startup code uses non-standard calling convention and intentionally
......
......@@ -11,11 +11,8 @@ go/types/scope.go: method WriteTo(w io.Writer, n int, recurse bool) should have
// Nothing much to do about cross-package assembly. Unfortunate.
runtime/asm_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: call is in package reflect
internal/bytealg/equal_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: Equal is in package bytes
internal/bytealg/equal_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: memequal is in package runtime
internal/bytealg/equal_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: memequal_varlen is in package runtime
internal/bytealg/indexbyte_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: IndexByte is in package bytes
internal/bytealg/indexbyte_ARCHSUFF.s: [GOARCH] cannot check cross-package assembly function: IndexByte is in package strings
// The write barrier is called directly by the compiler, so no Go def
runtime/asm_ARCHSUFF.s: [GOARCH] gcWriteBarrier: function gcWriteBarrier missing Go declaration
......
......@@ -3,7 +3,6 @@
// False positives.
// Nothing much to do about cross-package assembly. Unfortunate.
internal/bytealg/compare_amd64.s: [amd64] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_amd64.s: [amd64] cannot check cross-package assembly function: cmpstring is in package runtime
// reflect trampolines intentionally omit arg size. Same for morestack.
......
// arm-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_arm.s: [arm] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_arm.s: [arm] cannot check cross-package assembly function: cmpstring is in package runtime
// Intentionally missing declarations.
......
// arm64-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_arm64.s: [arm64] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_arm64.s: [arm64] cannot check cross-package assembly function: cmpstring is in package runtime
// Intentionally missing declarations.
......
// mips/mipsle-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_mipsx.s: [GOARCH] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_mipsx.s: [GOARCH] cannot check cross-package assembly function: cmpstring is in package runtime
runtime/tls_mipsx.s: [GOARCH] save_g: function save_g missing Go declaration
......
// nacl/amd64p32-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_amd64p32.s: [amd64p32] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_amd64p32.s: [amd64p32] cannot check cross-package assembly function: cmpstring is in package runtime
// reflect trampolines intentionally omit arg size. Same for morestack.
......
// ppc64-specific vet whitelist. See readme.txt for details.
internal/bytealg/compare_ppc64x.s: [GOARCH] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_ppc64x.s: [GOARCH] cannot check cross-package assembly function: cmpstring is in package runtime
runtime/asm_ppc64x.s: [GOARCH] reginit: function reginit missing Go declaration
......
internal/bytealg/compare_s390x.s: [s390x] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_s390x.s: [s390x] cannot check cross-package assembly function: cmpstring is in package runtime
runtime/asm_s390x.s: [s390x] addmoduledata: function addmoduledata missing Go declaration
runtime/memclr_s390x.s: [s390x] memclr_s390x_exrl_xc: function memclr_s390x_exrl_xc missing Go declaration
......
......@@ -3,7 +3,6 @@
// False positives.
// Nothing much to do about cross-package assembly. Unfortunate.
internal/bytealg/compare_wasm.s: [wasm] cannot check cross-package assembly function: Compare is in package bytes
internal/bytealg/compare_wasm.s: [wasm] cannot check cross-package assembly function: cmpstring is in package runtime
// morestack intentionally omits arg size.
......
......@@ -13,15 +13,6 @@ TEXT ·Compare(SB),NOSPLIT,$0-28
LEAL ret+24(FP), AX
JMP cmpbody<>(SB)
TEXT bytes·Compare(SB),NOSPLIT,$0-28
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVL a_base+0(FP), SI
MOVL a_len+4(FP), BX
MOVL b_base+12(FP), DI
MOVL b_len+16(FP), DX
LEAL ret+24(FP), AX
JMP cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
MOVL a_base+0(FP), SI
MOVL a_len+4(FP), BX
......
......@@ -13,15 +13,6 @@ TEXT ·Compare(SB),NOSPLIT,$0-56
LEAQ ret+48(FP), R9
JMP cmpbody<>(SB)
TEXT bytes·Compare(SB),NOSPLIT,$0-56
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVQ a_base+0(FP), SI
MOVQ a_len+8(FP), BX
MOVQ b_base+24(FP), DI
MOVQ b_len+32(FP), DX
LEAQ ret+48(FP), R9
JMP cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
MOVQ a_base+0(FP), SI
MOVQ a_len+8(FP), BX
......
......@@ -14,16 +14,6 @@ TEXT ·Compare(SB),NOSPLIT,$0-28
MOVL AX, ret+24(FP)
RET
TEXT bytes·Compare(SB),NOSPLIT,$0-28
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVL a_base+0(FP), SI
MOVL a_len+4(FP), BX
MOVL b_base+12(FP), DI
MOVL b_len+16(FP), DX
CALL cmpbody<>(SB)
MOVL AX, ret+24(FP)
RET
TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
MOVL a_base+0(FP), SI
MOVL a_len+4(FP), BX
......
......@@ -13,15 +13,6 @@ TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-28
ADD $28, R13, R7
B cmpbody<>(SB)
TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-28
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVW a_base+0(FP), R2
MOVW a_len+4(FP), R0
MOVW b_base+12(FP), R3
MOVW b_len+16(FP), R1
ADD $28, R13, R7
B cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20
MOVW a_base+0(FP), R2
MOVW a_len+4(FP), R0
......
......@@ -13,15 +13,6 @@ TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-56
MOVD $ret+48(FP), R7
B cmpbody<>(SB)
TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVD a_base+0(FP), R2
MOVD a_len+8(FP), R0
MOVD b_base+24(FP), R3
MOVD b_len+32(FP), R1
MOVD $ret+48(FP), R7
B cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40
MOVD a_base+0(FP), R2
MOVD a_len+8(FP), R0
......
......@@ -35,34 +35,6 @@ samebytes:
return 0
}
//go:linkname bytes_Compare bytes.Compare
func bytes_Compare(a, b []byte) int {
l := len(a)
if len(b) < l {
l = len(b)
}
if l == 0 || &a[0] == &b[0] {
goto samebytes
}
for i := 0; i < l; i++ {
c1, c2 := a[i], b[i]
if c1 < c2 {
return -1
}
if c1 > c2 {
return +1
}
}
samebytes:
if len(a) < len(b) {
return -1
}
if len(a) > len(b) {
return +1
}
return 0
}
//go:linkname runtime_cmpstring runtime.cmpstring
func runtime_cmpstring(a, b string) int {
l := len(a)
......
......@@ -39,39 +39,6 @@ cmp_ret:
MOVW R8, ret+24(FP)
RET
TEXT bytes·Compare(SB),NOSPLIT,$0-28
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVW a_base+0(FP), R3
MOVW b_base+12(FP), R4
MOVW a_len+4(FP), R1
MOVW b_len+16(FP), R2
BEQ R3, R4, samebytes
SGTU R1, R2, R7
MOVW R1, R8
CMOVN R7, R2, R8 // R8 is min(R1, R2)
ADDU R3, R8 // R3 is current byte in a, R8 is last byte in a to compare
loop:
BEQ R3, R8, samebytes
MOVBU (R3), R6
ADDU $1, R3
MOVBU (R4), R7
ADDU $1, R4
BEQ R6, R7 , loop
SGTU R6, R7, R8
MOVW $-1, R6
CMOVZ R8, R6, R8
JMP cmp_ret
samebytes:
SGTU R1, R2, R6
SGTU R2, R1, R7
SUBU R7, R6, R8
cmp_ret:
MOVW R8, ret+24(FP)
RET
TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
MOVW a_base+0(FP), R3
MOVW a_len+4(FP), R1
......
......@@ -23,37 +23,6 @@ TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-56
BR cmpbodyBE<>(SB)
#endif
equal:
BEQ CR6,done
MOVD $1, R8
BGT CR6,greater
NEG R8
greater:
MOVD R8, (R7)
RET
done:
MOVD $0, (R7)
RET
TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVD a_base+0(FP), R5
MOVD b_base+24(FP), R6
MOVD a_len+8(FP), R3
CMP R5,R6,CR7
MOVD b_len+32(FP), R4
MOVD $ret+48(FP), R7
CMP R3,R4,CR6
BEQ CR7,equal
#ifdef GOARCH_ppc64le
BR cmpbodyLE<>(SB)
#else
BR cmpbodyBE<>(SB)
#endif
equal:
BEQ CR6,done
MOVD $1, R8
......
......@@ -13,15 +13,6 @@ TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-56
LA ret+48(FP), R7
BR cmpbody<>(SB)
TEXT bytes·Compare(SB),NOSPLIT|NOFRAME,$0-56
FUNCDATA $0, ·Compare·args_stackmap(SB)
MOVD a_base+0(FP), R3
MOVD a_len+8(FP), R4
MOVD b_base+24(FP), R5
MOVD b_len+32(FP), R6
LA ret+48(FP), R7
BR cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40
MOVD a_base+0(FP), R3
MOVD a_len+8(FP), R4
......
......@@ -15,17 +15,6 @@ TEXT ·Compare(SB), NOSPLIT, $0-56
I64Store ret+48(FP)
RET
TEXT bytes·Compare(SB), NOSPLIT, $0-56
FUNCDATA $0, ·Compare·args_stackmap(SB)
Get SP
I64Load a_base+0(FP)
I64Load a_len+8(FP)
I64Load b_base+24(FP)
I64Load b_len+32(FP)
Call cmpbody<>(SB)
I64Store ret+48(FP)
RET
TEXT runtime·cmpstring(SB), NOSPLIT, $0-40
Get SP
I64Load a_base+0(FP)
......
......@@ -23,25 +23,6 @@ eq:
MOVB $1, ret+24(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-25
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVL a_len+4(FP), BX
MOVL b_len+16(FP), CX
CMPL BX, CX
JNE neq
MOVL a_base+0(FP), SI
MOVL b_base+12(FP), DI
CMPL SI, DI
JEQ eq
LEAL ret+24(FP), AX
JMP memeqbody<>(SB)
neq:
MOVB $0, ret+24(FP)
RET
eq:
MOVB $1, ret+24(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$0-13
MOVL a+0(FP), SI
......
......@@ -23,25 +23,6 @@ eq:
MOVB $1, ret+48(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVQ a_len+8(FP), BX
MOVQ b_len+32(FP), CX
CMPQ BX, CX
JNE neq
MOVQ a_base+0(FP), SI
MOVQ b_base+24(FP), DI
CMPQ SI, DI
JEQ eq
LEAQ ret+48(FP), AX
JMP memeqbody<>(SB)
neq:
MOVB $0, ret+48(FP)
RET
eq:
MOVB $1, ret+48(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$0-25
MOVQ a+0(FP), SI
......
......@@ -24,26 +24,6 @@ eq:
MOVB $1, ret+24(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-25
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVL a_len+4(FP), BX
MOVL b_len+16(FP), CX
CMPL BX, CX
JNE neq
MOVL a_base+0(FP), SI
MOVL b_base+12(FP), DI
CMPL SI, DI
JEQ eq
CALL memeqbody<>(SB)
MOVB AX, ret+24(FP)
RET
neq:
MOVB $0, ret+24(FP)
RET
eq:
MOVB $1, ret+24(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$0-17
MOVL a+0(FP), SI
......
......@@ -35,10 +35,6 @@ equal:
MOVBU R0, ret+24(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-25
FUNCDATA $0, ·Equal·args_stackmap(SB)
JMP ·Equal(SB)
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-13
MOVW a+0(FP), R1
......
......@@ -25,27 +25,6 @@ not_equal:
MOVB ZR, ret+48(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVD a_len+8(FP), R1
MOVD b_len+32(FP), R3
CMP R1, R3
// unequal lengths are not equal
BNE not_equal
// short path to handle 0-byte case
CBZ R1, equal
MOVD a_base+0(FP), R0
MOVD b_base+24(FP), R2
MOVD $ret+48(FP), R8
B memeqbody<>(SB)
equal:
MOVD $1, R0
MOVB R0, ret+48(FP)
RET
not_equal:
MOVB ZR, ret+48(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
MOVD size+16(FP), R1
......
......@@ -35,10 +35,6 @@ equal:
MOVB R1, ret+48(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
JMP ·Equal(SB)
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
MOVV a+0(FP), R1
......
......@@ -35,10 +35,6 @@ equal:
MOVB R1, ret+24(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT,$0-25
FUNCDATA $0, ·Equal·args_stackmap(SB)
JMP ·Equal(SB)
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT,$0-13
MOVW a+0(FP), R1
......
......@@ -26,26 +26,6 @@ equal:
MOVBZ R3,ret+48(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT|NOFRAME,$0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVD a_len+8(FP), R4
MOVD b_len+32(FP), R5
CMP R5, R4 // unequal lengths are not equal
BNE noteq
MOVD a_base+0(FP), R3
MOVD b_base+24(FP), R4
MOVD $ret+48(FP), R10
BR memeqbody<>(SB)
noteq:
MOVBZ $0,ret+48(FP)
RET
equal:
MOVD $1,R3
MOVBZ R3,ret+48(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
MOVD a+0(FP), R3
......
......@@ -17,19 +17,6 @@ notequal:
MOVB $0, ret+48(FP)
RET
TEXT bytes·Equal(SB),NOSPLIT|NOFRAME,$0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVD a_len+8(FP), R2
MOVD b_len+32(FP), R6
MOVD a_base+0(FP), R3
MOVD b_base+24(FP), R5
LA ret+48(FP), R7
CMPBNE R2, R6, notequal
BR memeqbody<>(SB)
notequal:
MOVB $0, ret+48(FP)
RET
// memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25
MOVD a+0(FP), R3
......
......@@ -25,27 +25,6 @@ TEXT ·Equal(SB), NOSPLIT, $0-49
End
RET
TEXT bytes·Equal(SB), NOSPLIT, $0-49
FUNCDATA $0, ·Equal·args_stackmap(SB)
MOVD a_len+8(FP), R0
MOVD b_len+32(FP), R1
Get R0
Get R1
I64Eq
If
Get SP
I64Load a+0(FP)
I64Load b+24(FP)
Get R0
Call memeqbody<>(SB)
I64Store8 ret+48(FP)
Else
Get SP
I64Const $0
I64Store8 ret+48(FP)
End
RET
// memequal(p, q unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal(SB), NOSPLIT, $0-25
Get SP
......
......@@ -32,11 +32,3 @@ TEXT ·IndexByteString(SB),NOSPLIT,$0-16
SUBL $1, DI
MOVL DI, ret+12(FP)
RET
TEXT bytes·IndexByte(SB),NOSPLIT,$0-20
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
JMP ·IndexByte(SB)
TEXT strings·IndexByte(SB),NOSPLIT,$0-16
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
JMP ·IndexByteString(SB)
......@@ -19,30 +19,6 @@ TEXT ·IndexByteString(SB), NOSPLIT, $0-32
LEAQ ret+24(FP), R8
JMP indexbytebody<>(SB)
// Provide direct access to these functions from other packages.
// This is the equivlant of doing:
// package bytes
// func IndexByte(b []byte, c byte) int {
// return bytealg.IndexByte(s, c)
// }
// but involves no call overhead.
// TODO: remove this hack when midstack inlining is enabled?
TEXT bytes·IndexByte(SB), NOSPLIT, $0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
MOVQ b_base+0(FP), SI
MOVQ b_len+8(FP), BX
MOVB c+24(FP), AL
LEAQ ret+32(FP), R8
JMP indexbytebody<>(SB)
TEXT strings·IndexByte(SB), NOSPLIT, $0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
MOVQ s_base+0(FP), SI
MOVQ s_len+8(FP), BX
MOVB c+16(FP), AL
LEAQ ret+24(FP), R8
JMP indexbytebody<>(SB)
// input:
// SI: data
// BX: data len
......
......@@ -21,24 +21,6 @@ TEXT ·IndexByteString(SB),NOSPLIT,$0-20
MOVL AX, ret+16(FP)
RET
TEXT bytes·IndexByte(SB),NOSPLIT,$0-20
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
MOVL b_base+0(FP), SI
MOVL b_len+4(FP), BX
MOVB c+12(FP), AL
CALL indexbytebody<>(SB)
MOVL AX, ret+16(FP)
RET
TEXT strings·IndexByte(SB),NOSPLIT,$0-20
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
MOVL s_base+0(FP), SI
MOVL s_len+4(FP), BX
MOVB c+8(FP), AL
CALL indexbytebody<>(SB)
MOVL AX, ret+16(FP)
RET
// input:
// SI: data
// BX: data len
......
......@@ -52,11 +52,3 @@ _sib_notfound:
MOVW $-1, R0
MOVW R0, ret+12(FP)
RET
TEXT bytes·IndexByte(SB),NOSPLIT,$0-20
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
JMP ·IndexByte(SB)
TEXT strings·IndexByte(SB),NOSPLIT,$0-16
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
JMP ·IndexByteString(SB)
......@@ -18,22 +18,6 @@ TEXT ·IndexByteString(SB),NOSPLIT,$0-32
MOVD $ret+24(FP), R8
B indexbytebody<>(SB)
TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
MOVD b_base+0(FP), R0
MOVD b_len+8(FP), R2
MOVBU c+24(FP), R1
MOVD $ret+32(FP), R8
B indexbytebody<>(SB)
TEXT strings·IndexByte(SB),NOSPLIT,$0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
MOVD s_base+0(FP), R0
MOVD s_len+8(FP), R2
MOVBU c+16(FP), R1
MOVD $ret+24(FP), R8
B indexbytebody<>(SB)
// input:
// R0: data
// R1: byte to search
......
......@@ -6,8 +6,6 @@
package bytealg
import _ "unsafe" // for go:linkname
func IndexByte(b []byte, c byte) int {
for i, x := range b {
if x == c {
......@@ -25,23 +23,3 @@ func IndexByteString(s string, c byte) int {
}
return -1
}
//go:linkname bytes_IndexByte bytes.IndexByte
func bytes_IndexByte(b []byte, c byte) int {
for i, x := range b {
if x == c {
return i
}
}
return -1
}
//go:linkname strings_IndexByte strings.IndexByte
func strings_IndexByte(s string, c byte) int {
for i := 0; i < len(s); i++ {
if s[i] == c {
return i
}
}
return -1
}
......@@ -52,11 +52,3 @@ notfound:
MOVV $-1, R1
MOVV R1, ret+24(FP)
RET
TEXT bytes·IndexByte(SB),NOSPLIT,$0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
JMP ·IndexByte(SB)
TEXT strings·IndexByte(SB),NOSPLIT,$0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
JMP ·IndexByteString(SB)
......@@ -50,11 +50,3 @@ notfound:
MOVW $-1, R1
MOVW R1, ret+12(FP)
RET
TEXT bytes·IndexByte(SB),NOSPLIT,$0-20
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
JMP ·IndexByte(SB)
TEXT strings·IndexByte(SB),NOSPLIT,$0-16
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
JMP ·IndexByteString(SB)
......@@ -21,22 +21,6 @@ TEXT ·IndexByteString(SB),NOSPLIT|NOFRAME,$0-32
MOVD $ret+24(FP), R14 // R14 = &ret
BR indexbytebody<>(SB)
TEXT bytes·IndexByte(SB),NOSPLIT|NOFRAME,$0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
MOVD b_base+0(FP), R3 // R3 = byte array pointer
MOVD b_len+8(FP), R4 // R4 = length
MOVBZ c+24(FP), R5 // R5 = byte
MOVD $ret+32(FP), R14 // R14 = &ret
BR indexbytebody<>(SB)
TEXT strings·IndexByte(SB),NOSPLIT|NOFRAME,$0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
MOVD s_base+0(FP), R3 // R3 = string
MOVD s_len+8(FP), R4 // R4 = length
MOVBZ c+16(FP), R5 // R5 = byte
MOVD $ret+24(FP), R14 // R14 = &ret
BR indexbytebody<>(SB)
TEXT indexbytebody<>(SB),NOSPLIT|NOFRAME,$0-0
MOVD R3,R17 // Save base address for calculating the index later.
RLDICR $0,R3,$60,R8 // Align address to doubleword boundary in R8.
......
......@@ -19,22 +19,6 @@ TEXT ·IndexByteString(SB),NOSPLIT|NOFRAME,$0-32
MOVD $ret+24(FP), R2 // &ret => R9
BR indexbytebody<>(SB)
TEXT bytes·IndexByte(SB),NOSPLIT|NOFRAME,$0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
MOVD b_base+0(FP), R3// b_base => R3
MOVD b_len+8(FP), R4 // b_len => R4
MOVBZ c+24(FP), R5 // c => R5
MOVD $ret+32(FP), R2 // &ret => R9
BR indexbytebody<>(SB)
TEXT strings·IndexByte(SB),NOSPLIT|NOFRAME,$0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
MOVD s_base+0(FP), R3// s_base => R3
MOVD s_len+8(FP), R4 // s_len => R4
MOVBZ c+16(FP), R5 // c => R5
MOVD $ret+24(FP), R2 // &ret => R9
BR indexbytebody<>(SB)
// input:
// R3: s
// R4: s_len
......
......@@ -49,51 +49,6 @@ TEXT ·IndexByteString(SB), NOSPLIT, $0-32
RET
TEXT bytes·IndexByte(SB), NOSPLIT, $0-40
FUNCDATA $0, ·IndexByte·args_stackmap(SB)
Get SP
I64Load b_base+0(FP)
I32WrapI64
I32Load8U c+24(FP)
I64Load b_len+8(FP)
I32WrapI64
Call memchr<>(SB)
I64ExtendSI32
Set R0
I64Const $-1
Get R0
I64Load b_base+0(FP)
I64Sub
Get R0
I64Eqz $0
Select
I64Store ret+32(FP)
RET
TEXT strings·IndexByte(SB), NOSPLIT, $0-32
FUNCDATA $0, ·IndexByteString·args_stackmap(SB)
Get SP
I64Load s_base+0(FP)
I32WrapI64
I32Load8U c+16(FP)
I64Load s_len+8(FP)
I32WrapI64
Call memchr<>(SB)
I64ExtendSI32
Set R0
I64Const $-1
Get R0
I64Load s_base+0(FP)
I64Sub
Get R0
I64Eqz $0
Select
I64Store ret+24(FP)
RET
// compiled with emscripten
// params: s, c, len
// ret: index
......
......@@ -146,6 +146,11 @@ func LastIndex(s, substr 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 {
return bytealg.IndexByteString(s, c)
}
// IndexRune returns the index of the first instance of the Unicode code point
// r, or -1 if rune is not present in s.
// If r is utf8.RuneError, it returns the first instance of any
......
// 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
//go:noescape
// 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 // in internal/bytealg
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment