fix(go.sum): update ResolveSpec dependency to v1.0.87
This commit is contained in:
+53
@@ -0,0 +1,53 @@
|
||||
package ascii
|
||||
|
||||
import _ "github.com/segmentio/asm/cpu"
|
||||
|
||||
// https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
|
||||
const (
|
||||
hasLessConstL64 = (^uint64(0)) / 255
|
||||
hasLessConstR64 = hasLessConstL64 * 128
|
||||
|
||||
hasLessConstL32 = (^uint32(0)) / 255
|
||||
hasLessConstR32 = hasLessConstL32 * 128
|
||||
|
||||
hasMoreConstL64 = (^uint64(0)) / 255
|
||||
hasMoreConstR64 = hasMoreConstL64 * 128
|
||||
|
||||
hasMoreConstL32 = (^uint32(0)) / 255
|
||||
hasMoreConstR32 = hasMoreConstL32 * 128
|
||||
)
|
||||
|
||||
func hasLess64(x, n uint64) bool {
|
||||
return ((x - (hasLessConstL64 * n)) & ^x & hasLessConstR64) != 0
|
||||
}
|
||||
|
||||
func hasLess32(x, n uint32) bool {
|
||||
return ((x - (hasLessConstL32 * n)) & ^x & hasLessConstR32) != 0
|
||||
}
|
||||
|
||||
func hasMore64(x, n uint64) bool {
|
||||
return (((x + (hasMoreConstL64 * (127 - n))) | x) & hasMoreConstR64) != 0
|
||||
}
|
||||
|
||||
func hasMore32(x, n uint32) bool {
|
||||
return (((x + (hasMoreConstL32 * (127 - n))) | x) & hasMoreConstR32) != 0
|
||||
}
|
||||
|
||||
var lowerCase = [256]byte{
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
|
||||
0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
|
||||
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
|
||||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
|
||||
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
|
||||
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
|
||||
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
|
||||
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
|
||||
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
|
||||
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package ascii
|
||||
|
||||
import (
|
||||
"github.com/segmentio/asm/internal/unsafebytes"
|
||||
)
|
||||
|
||||
// EqualFold is a version of bytes.EqualFold designed to work on ASCII input
|
||||
// instead of UTF-8.
|
||||
//
|
||||
// When the program has guarantees that the input is composed of ASCII
|
||||
// characters only, it allows for greater optimizations.
|
||||
func EqualFold(a, b []byte) bool {
|
||||
return EqualFoldString(unsafebytes.String(a), unsafebytes.String(b))
|
||||
}
|
||||
|
||||
func HasPrefixFold(s, prefix []byte) bool {
|
||||
return len(s) >= len(prefix) && EqualFold(s[:len(prefix)], prefix)
|
||||
}
|
||||
|
||||
func HasSuffixFold(s, suffix []byte) bool {
|
||||
return len(s) >= len(suffix) && EqualFold(s[len(s)-len(suffix):], suffix)
|
||||
}
|
||||
|
||||
func HasPrefixFoldString(s, prefix string) bool {
|
||||
return len(s) >= len(prefix) && EqualFoldString(s[:len(prefix)], prefix)
|
||||
}
|
||||
|
||||
func HasSuffixFoldString(s, suffix string) bool {
|
||||
return len(s) >= len(suffix) && EqualFoldString(s[len(s)-len(suffix):], suffix)
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// Code generated by command: go run equal_fold_asm.go -pkg ascii -out ../ascii/equal_fold_amd64.s -stubs ../ascii/equal_fold_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
package ascii
|
||||
|
||||
// EqualFoldString is a version of strings.EqualFold designed to work on ASCII
|
||||
// input instead of UTF-8.
|
||||
//
|
||||
// When the program has guarantees that the input is composed of ASCII
|
||||
// characters only, it allows for greater optimizations.
|
||||
func EqualFoldString(a string, b string) bool
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
// Code generated by command: go run equal_fold_asm.go -pkg ascii -out ../ascii/equal_fold_amd64.s -stubs ../ascii/equal_fold_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func EqualFoldString(a string, b string) bool
|
||||
// Requires: AVX, AVX2, SSE4.1
|
||||
TEXT ·EqualFoldString(SB), NOSPLIT, $0-33
|
||||
MOVQ a_base+0(FP), CX
|
||||
MOVQ a_len+8(FP), DX
|
||||
MOVQ b_base+16(FP), BX
|
||||
CMPQ DX, b_len+24(FP)
|
||||
JNE done
|
||||
XORQ AX, AX
|
||||
CMPQ DX, $0x10
|
||||
JB init_x86
|
||||
BTL $0x08, github·com∕segmentio∕asm∕cpu·X86+0(SB)
|
||||
JCS init_avx
|
||||
|
||||
init_x86:
|
||||
LEAQ github·com∕segmentio∕asm∕ascii·lowerCase+0(SB), R9
|
||||
XORL SI, SI
|
||||
|
||||
cmp8:
|
||||
CMPQ DX, $0x08
|
||||
JB cmp7
|
||||
MOVBLZX (CX)(AX*1), DI
|
||||
MOVBLZX (BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 1(CX)(AX*1), DI
|
||||
MOVBLZX 1(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 2(CX)(AX*1), DI
|
||||
MOVBLZX 2(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 3(CX)(AX*1), DI
|
||||
MOVBLZX 3(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 4(CX)(AX*1), DI
|
||||
MOVBLZX 4(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 5(CX)(AX*1), DI
|
||||
MOVBLZX 5(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 6(CX)(AX*1), DI
|
||||
MOVBLZX 6(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
MOVBLZX 7(CX)(AX*1), DI
|
||||
MOVBLZX 7(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
JNE done
|
||||
ADDQ $0x08, AX
|
||||
SUBQ $0x08, DX
|
||||
JMP cmp8
|
||||
|
||||
cmp7:
|
||||
CMPQ DX, $0x07
|
||||
JB cmp6
|
||||
MOVBLZX 6(CX)(AX*1), DI
|
||||
MOVBLZX 6(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp6:
|
||||
CMPQ DX, $0x06
|
||||
JB cmp5
|
||||
MOVBLZX 5(CX)(AX*1), DI
|
||||
MOVBLZX 5(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp5:
|
||||
CMPQ DX, $0x05
|
||||
JB cmp4
|
||||
MOVBLZX 4(CX)(AX*1), DI
|
||||
MOVBLZX 4(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp4:
|
||||
CMPQ DX, $0x04
|
||||
JB cmp3
|
||||
MOVBLZX 3(CX)(AX*1), DI
|
||||
MOVBLZX 3(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp3:
|
||||
CMPQ DX, $0x03
|
||||
JB cmp2
|
||||
MOVBLZX 2(CX)(AX*1), DI
|
||||
MOVBLZX 2(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp2:
|
||||
CMPQ DX, $0x02
|
||||
JB cmp1
|
||||
MOVBLZX 1(CX)(AX*1), DI
|
||||
MOVBLZX 1(BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
cmp1:
|
||||
CMPQ DX, $0x01
|
||||
JB success
|
||||
MOVBLZX (CX)(AX*1), DI
|
||||
MOVBLZX (BX)(AX*1), R8
|
||||
MOVB (R9)(DI*1), DI
|
||||
XORB (R9)(R8*1), DI
|
||||
ORB DI, SI
|
||||
|
||||
done:
|
||||
SETEQ ret+32(FP)
|
||||
RET
|
||||
|
||||
success:
|
||||
MOVB $0x01, ret+32(FP)
|
||||
RET
|
||||
|
||||
init_avx:
|
||||
MOVB $0x20, SI
|
||||
PINSRB $0x00, SI, X12
|
||||
VPBROADCASTB X12, Y12
|
||||
MOVB $0x1f, SI
|
||||
PINSRB $0x00, SI, X13
|
||||
VPBROADCASTB X13, Y13
|
||||
MOVB $0x9a, SI
|
||||
PINSRB $0x00, SI, X14
|
||||
VPBROADCASTB X14, Y14
|
||||
MOVB $0x01, SI
|
||||
PINSRB $0x00, SI, X15
|
||||
VPBROADCASTB X15, Y15
|
||||
|
||||
cmp128:
|
||||
CMPQ DX, $0x80
|
||||
JB cmp64
|
||||
VMOVDQU (CX)(AX*1), Y0
|
||||
VMOVDQU 32(CX)(AX*1), Y1
|
||||
VMOVDQU 64(CX)(AX*1), Y2
|
||||
VMOVDQU 96(CX)(AX*1), Y3
|
||||
VMOVDQU (BX)(AX*1), Y4
|
||||
VMOVDQU 32(BX)(AX*1), Y5
|
||||
VMOVDQU 64(BX)(AX*1), Y6
|
||||
VMOVDQU 96(BX)(AX*1), Y7
|
||||
VXORPD Y0, Y4, Y4
|
||||
VPCMPEQB Y12, Y4, Y8
|
||||
VORPD Y12, Y0, Y0
|
||||
VPADDB Y13, Y0, Y0
|
||||
VPCMPGTB Y0, Y14, Y0
|
||||
VPAND Y8, Y0, Y0
|
||||
VPAND Y15, Y0, Y0
|
||||
VPSLLW $0x05, Y0, Y0
|
||||
VPCMPEQB Y4, Y0, Y0
|
||||
VXORPD Y1, Y5, Y5
|
||||
VPCMPEQB Y12, Y5, Y9
|
||||
VORPD Y12, Y1, Y1
|
||||
VPADDB Y13, Y1, Y1
|
||||
VPCMPGTB Y1, Y14, Y1
|
||||
VPAND Y9, Y1, Y1
|
||||
VPAND Y15, Y1, Y1
|
||||
VPSLLW $0x05, Y1, Y1
|
||||
VPCMPEQB Y5, Y1, Y1
|
||||
VXORPD Y2, Y6, Y6
|
||||
VPCMPEQB Y12, Y6, Y10
|
||||
VORPD Y12, Y2, Y2
|
||||
VPADDB Y13, Y2, Y2
|
||||
VPCMPGTB Y2, Y14, Y2
|
||||
VPAND Y10, Y2, Y2
|
||||
VPAND Y15, Y2, Y2
|
||||
VPSLLW $0x05, Y2, Y2
|
||||
VPCMPEQB Y6, Y2, Y2
|
||||
VXORPD Y3, Y7, Y7
|
||||
VPCMPEQB Y12, Y7, Y11
|
||||
VORPD Y12, Y3, Y3
|
||||
VPADDB Y13, Y3, Y3
|
||||
VPCMPGTB Y3, Y14, Y3
|
||||
VPAND Y11, Y3, Y3
|
||||
VPAND Y15, Y3, Y3
|
||||
VPSLLW $0x05, Y3, Y3
|
||||
VPCMPEQB Y7, Y3, Y3
|
||||
VPAND Y1, Y0, Y0
|
||||
VPAND Y3, Y2, Y2
|
||||
VPAND Y2, Y0, Y0
|
||||
ADDQ $0x80, AX
|
||||
SUBQ $0x80, DX
|
||||
VPMOVMSKB Y0, SI
|
||||
XORL $0xffffffff, SI
|
||||
JNE done
|
||||
JMP cmp128
|
||||
|
||||
cmp64:
|
||||
CMPQ DX, $0x40
|
||||
JB cmp32
|
||||
VMOVDQU (CX)(AX*1), Y0
|
||||
VMOVDQU 32(CX)(AX*1), Y1
|
||||
VMOVDQU (BX)(AX*1), Y2
|
||||
VMOVDQU 32(BX)(AX*1), Y3
|
||||
VXORPD Y0, Y2, Y2
|
||||
VPCMPEQB Y12, Y2, Y4
|
||||
VORPD Y12, Y0, Y0
|
||||
VPADDB Y13, Y0, Y0
|
||||
VPCMPGTB Y0, Y14, Y0
|
||||
VPAND Y4, Y0, Y0
|
||||
VPAND Y15, Y0, Y0
|
||||
VPSLLW $0x05, Y0, Y0
|
||||
VPCMPEQB Y2, Y0, Y0
|
||||
VXORPD Y1, Y3, Y3
|
||||
VPCMPEQB Y12, Y3, Y5
|
||||
VORPD Y12, Y1, Y1
|
||||
VPADDB Y13, Y1, Y1
|
||||
VPCMPGTB Y1, Y14, Y1
|
||||
VPAND Y5, Y1, Y1
|
||||
VPAND Y15, Y1, Y1
|
||||
VPSLLW $0x05, Y1, Y1
|
||||
VPCMPEQB Y3, Y1, Y1
|
||||
VPAND Y1, Y0, Y0
|
||||
ADDQ $0x40, AX
|
||||
SUBQ $0x40, DX
|
||||
VPMOVMSKB Y0, SI
|
||||
XORL $0xffffffff, SI
|
||||
JNE done
|
||||
|
||||
cmp32:
|
||||
CMPQ DX, $0x20
|
||||
JB cmp16
|
||||
VMOVDQU (CX)(AX*1), Y0
|
||||
VMOVDQU (BX)(AX*1), Y1
|
||||
VXORPD Y0, Y1, Y1
|
||||
VPCMPEQB Y12, Y1, Y2
|
||||
VORPD Y12, Y0, Y0
|
||||
VPADDB Y13, Y0, Y0
|
||||
VPCMPGTB Y0, Y14, Y0
|
||||
VPAND Y2, Y0, Y0
|
||||
VPAND Y15, Y0, Y0
|
||||
VPSLLW $0x05, Y0, Y0
|
||||
VPCMPEQB Y1, Y0, Y0
|
||||
ADDQ $0x20, AX
|
||||
SUBQ $0x20, DX
|
||||
VPMOVMSKB Y0, SI
|
||||
XORL $0xffffffff, SI
|
||||
JNE done
|
||||
|
||||
cmp16:
|
||||
CMPQ DX, $0x10
|
||||
JLE cmp_tail
|
||||
VMOVDQU (CX)(AX*1), X0
|
||||
VMOVDQU (BX)(AX*1), X1
|
||||
VXORPD X0, X1, X1
|
||||
VPCMPEQB X12, X1, X2
|
||||
VORPD X12, X0, X0
|
||||
VPADDB X13, X0, X0
|
||||
VPCMPGTB X0, X14, X0
|
||||
VPAND X2, X0, X0
|
||||
VPAND X15, X0, X0
|
||||
VPSLLW $0x05, X0, X0
|
||||
VPCMPEQB X1, X0, X0
|
||||
ADDQ $0x10, AX
|
||||
SUBQ $0x10, DX
|
||||
VPMOVMSKB X0, SI
|
||||
XORL $0x0000ffff, SI
|
||||
JNE done
|
||||
|
||||
cmp_tail:
|
||||
SUBQ $0x10, DX
|
||||
ADDQ DX, AX
|
||||
VMOVDQU (CX)(AX*1), X0
|
||||
VMOVDQU (BX)(AX*1), X1
|
||||
VXORPD X0, X1, X1
|
||||
VPCMPEQB X12, X1, X2
|
||||
VORPD X12, X0, X0
|
||||
VPADDB X13, X0, X0
|
||||
VPCMPGTB X0, X14, X0
|
||||
VPAND X2, X0, X0
|
||||
VPAND X15, X0, X0
|
||||
VPSLLW $0x05, X0, X0
|
||||
VPCMPEQB X1, X0, X0
|
||||
VPMOVMSKB X0, AX
|
||||
XORL $0x0000ffff, AX
|
||||
JMP done
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
//go:build purego || !amd64
|
||||
// +build purego !amd64
|
||||
|
||||
package ascii
|
||||
|
||||
// EqualFoldString is a version of strings.EqualFold designed to work on ASCII
|
||||
// input instead of UTF-8.
|
||||
//
|
||||
// When the program has guarantees that the input is composed of ASCII
|
||||
// characters only, it allows for greater optimizations.
|
||||
func EqualFoldString(a, b string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
var cmp byte
|
||||
|
||||
for len(a) >= 8 {
|
||||
cmp |= lowerCase[a[0]] ^ lowerCase[b[0]]
|
||||
cmp |= lowerCase[a[1]] ^ lowerCase[b[1]]
|
||||
cmp |= lowerCase[a[2]] ^ lowerCase[b[2]]
|
||||
cmp |= lowerCase[a[3]] ^ lowerCase[b[3]]
|
||||
cmp |= lowerCase[a[4]] ^ lowerCase[b[4]]
|
||||
cmp |= lowerCase[a[5]] ^ lowerCase[b[5]]
|
||||
cmp |= lowerCase[a[6]] ^ lowerCase[b[6]]
|
||||
cmp |= lowerCase[a[7]] ^ lowerCase[b[7]]
|
||||
|
||||
if cmp != 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
a = a[8:]
|
||||
b = b[8:]
|
||||
}
|
||||
|
||||
switch len(a) {
|
||||
case 7:
|
||||
cmp |= lowerCase[a[6]] ^ lowerCase[b[6]]
|
||||
fallthrough
|
||||
case 6:
|
||||
cmp |= lowerCase[a[5]] ^ lowerCase[b[5]]
|
||||
fallthrough
|
||||
case 5:
|
||||
cmp |= lowerCase[a[4]] ^ lowerCase[b[4]]
|
||||
fallthrough
|
||||
case 4:
|
||||
cmp |= lowerCase[a[3]] ^ lowerCase[b[3]]
|
||||
fallthrough
|
||||
case 3:
|
||||
cmp |= lowerCase[a[2]] ^ lowerCase[b[2]]
|
||||
fallthrough
|
||||
case 2:
|
||||
cmp |= lowerCase[a[1]] ^ lowerCase[b[1]]
|
||||
fallthrough
|
||||
case 1:
|
||||
cmp |= lowerCase[a[0]] ^ lowerCase[b[0]]
|
||||
}
|
||||
|
||||
return cmp == 0
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package ascii
|
||||
|
||||
import "github.com/segmentio/asm/internal/unsafebytes"
|
||||
|
||||
// Valid returns true if b contains only ASCII characters.
|
||||
func Valid(b []byte) bool {
|
||||
return ValidString(unsafebytes.String(b))
|
||||
}
|
||||
|
||||
// ValidBytes returns true if b is an ASCII character.
|
||||
func ValidByte(b byte) bool {
|
||||
return b <= 0x7f
|
||||
}
|
||||
|
||||
// ValidBytes returns true if b is an ASCII character.
|
||||
func ValidRune(r rune) bool {
|
||||
return r <= 0x7f
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by command: go run valid_asm.go -pkg ascii -out ../ascii/valid_amd64.s -stubs ../ascii/valid_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
package ascii
|
||||
|
||||
// ValidString returns true if s contains only ASCII characters.
|
||||
func ValidString(s string) bool
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
// Code generated by command: go run valid_asm.go -pkg ascii -out ../ascii/valid_amd64.s -stubs ../ascii/valid_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func ValidString(s string) bool
|
||||
// Requires: AVX, AVX2, SSE4.1
|
||||
TEXT ·ValidString(SB), NOSPLIT, $0-17
|
||||
MOVQ s_base+0(FP), AX
|
||||
MOVQ s_len+8(FP), CX
|
||||
MOVQ $0x8080808080808080, DX
|
||||
CMPQ CX, $0x10
|
||||
JB cmp8
|
||||
BTL $0x08, github·com∕segmentio∕asm∕cpu·X86+0(SB)
|
||||
JCS init_avx
|
||||
|
||||
cmp8:
|
||||
CMPQ CX, $0x08
|
||||
JB cmp4
|
||||
TESTQ DX, (AX)
|
||||
JNZ invalid
|
||||
ADDQ $0x08, AX
|
||||
SUBQ $0x08, CX
|
||||
JMP cmp8
|
||||
|
||||
cmp4:
|
||||
CMPQ CX, $0x04
|
||||
JB cmp3
|
||||
TESTL $0x80808080, (AX)
|
||||
JNZ invalid
|
||||
ADDQ $0x04, AX
|
||||
SUBQ $0x04, CX
|
||||
|
||||
cmp3:
|
||||
CMPQ CX, $0x03
|
||||
JB cmp2
|
||||
MOVWLZX (AX), CX
|
||||
MOVBLZX 2(AX), AX
|
||||
SHLL $0x10, AX
|
||||
ORL CX, AX
|
||||
TESTL $0x80808080, AX
|
||||
JMP done
|
||||
|
||||
cmp2:
|
||||
CMPQ CX, $0x02
|
||||
JB cmp1
|
||||
TESTW $0x8080, (AX)
|
||||
JMP done
|
||||
|
||||
cmp1:
|
||||
CMPQ CX, $0x00
|
||||
JE done
|
||||
TESTB $0x80, (AX)
|
||||
|
||||
done:
|
||||
SETEQ ret+16(FP)
|
||||
RET
|
||||
|
||||
invalid:
|
||||
MOVB $0x00, ret+16(FP)
|
||||
RET
|
||||
|
||||
init_avx:
|
||||
PINSRQ $0x00, DX, X4
|
||||
VPBROADCASTQ X4, Y4
|
||||
|
||||
cmp256:
|
||||
CMPQ CX, $0x00000100
|
||||
JB cmp128
|
||||
VMOVDQU (AX), Y0
|
||||
VPOR 32(AX), Y0, Y0
|
||||
VMOVDQU 64(AX), Y1
|
||||
VPOR 96(AX), Y1, Y1
|
||||
VMOVDQU 128(AX), Y2
|
||||
VPOR 160(AX), Y2, Y2
|
||||
VMOVDQU 192(AX), Y3
|
||||
VPOR 224(AX), Y3, Y3
|
||||
VPOR Y1, Y0, Y0
|
||||
VPOR Y3, Y2, Y2
|
||||
VPOR Y2, Y0, Y0
|
||||
VPTEST Y0, Y4
|
||||
JNZ invalid
|
||||
ADDQ $0x00000100, AX
|
||||
SUBQ $0x00000100, CX
|
||||
JMP cmp256
|
||||
|
||||
cmp128:
|
||||
CMPQ CX, $0x80
|
||||
JB cmp64
|
||||
VMOVDQU (AX), Y0
|
||||
VPOR 32(AX), Y0, Y0
|
||||
VMOVDQU 64(AX), Y1
|
||||
VPOR 96(AX), Y1, Y1
|
||||
VPOR Y1, Y0, Y0
|
||||
VPTEST Y0, Y4
|
||||
JNZ invalid
|
||||
ADDQ $0x80, AX
|
||||
SUBQ $0x80, CX
|
||||
|
||||
cmp64:
|
||||
CMPQ CX, $0x40
|
||||
JB cmp32
|
||||
VMOVDQU (AX), Y0
|
||||
VPOR 32(AX), Y0, Y0
|
||||
VPTEST Y0, Y4
|
||||
JNZ invalid
|
||||
ADDQ $0x40, AX
|
||||
SUBQ $0x40, CX
|
||||
|
||||
cmp32:
|
||||
CMPQ CX, $0x20
|
||||
JB cmp16
|
||||
VPTEST (AX), Y4
|
||||
JNZ invalid
|
||||
ADDQ $0x20, AX
|
||||
SUBQ $0x20, CX
|
||||
|
||||
cmp16:
|
||||
CMPQ CX, $0x10
|
||||
JLE cmp_tail
|
||||
VPTEST (AX), X4
|
||||
JNZ invalid
|
||||
ADDQ $0x10, AX
|
||||
SUBQ $0x10, CX
|
||||
|
||||
cmp_tail:
|
||||
SUBQ $0x10, CX
|
||||
ADDQ CX, AX
|
||||
VPTEST (AX), X4
|
||||
JMP done
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
//go:build purego || !amd64
|
||||
// +build purego !amd64
|
||||
|
||||
package ascii
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// ValidString returns true if s contains only ASCII characters.
|
||||
func ValidString(s string) bool {
|
||||
p := *(*unsafe.Pointer)(unsafe.Pointer(&s))
|
||||
i := uintptr(0)
|
||||
n := uintptr(len(s))
|
||||
|
||||
for i+8 <= n {
|
||||
if (*(*uint64)(unsafe.Pointer(uintptr(p) + i)) & 0x8080808080808080) != 0 {
|
||||
return false
|
||||
}
|
||||
i += 8
|
||||
}
|
||||
|
||||
if i+4 <= n {
|
||||
if (*(*uint32)(unsafe.Pointer(uintptr(p) + i)) & 0x80808080) != 0 {
|
||||
return false
|
||||
}
|
||||
i += 4
|
||||
}
|
||||
|
||||
if i == n {
|
||||
return true
|
||||
}
|
||||
|
||||
p = unsafe.Pointer(uintptr(p) + i)
|
||||
|
||||
var x uint32
|
||||
switch n - i {
|
||||
case 3:
|
||||
x = uint32(*(*uint16)(p)) | uint32(*(*uint8)(unsafe.Pointer(uintptr(p) + 2)))<<16
|
||||
case 2:
|
||||
x = uint32(*(*uint16)(p))
|
||||
case 1:
|
||||
x = uint32(*(*uint8)(p))
|
||||
default:
|
||||
return true
|
||||
}
|
||||
return (x & 0x80808080) == 0
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package ascii
|
||||
|
||||
import "github.com/segmentio/asm/internal/unsafebytes"
|
||||
|
||||
// ValidPrint returns true if b contains only printable ASCII characters.
|
||||
func ValidPrint(b []byte) bool {
|
||||
return ValidPrintString(unsafebytes.String(b))
|
||||
}
|
||||
|
||||
// ValidPrintBytes returns true if b is an ASCII character.
|
||||
func ValidPrintByte(b byte) bool {
|
||||
return 0x20 <= b && b <= 0x7e
|
||||
}
|
||||
|
||||
// ValidPrintBytes returns true if b is an ASCII character.
|
||||
func ValidPrintRune(r rune) bool {
|
||||
return 0x20 <= r && r <= 0x7e
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// Code generated by command: go run valid_print_asm.go -pkg ascii -out ../ascii/valid_print_amd64.s -stubs ../ascii/valid_print_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
package ascii
|
||||
|
||||
// ValidPrintString returns true if s contains only printable ASCII characters.
|
||||
func ValidPrintString(s string) bool
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
// Code generated by command: go run valid_print_asm.go -pkg ascii -out ../ascii/valid_print_amd64.s -stubs ../ascii/valid_print_amd64.go. DO NOT EDIT.
|
||||
|
||||
//go:build !purego
|
||||
// +build !purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func ValidPrintString(s string) bool
|
||||
// Requires: AVX, AVX2, SSE4.1
|
||||
TEXT ·ValidPrintString(SB), NOSPLIT, $0-17
|
||||
MOVQ s_base+0(FP), AX
|
||||
MOVQ s_len+8(FP), CX
|
||||
CMPQ CX, $0x10
|
||||
JB init_x86
|
||||
BTL $0x08, github·com∕segmentio∕asm∕cpu·X86+0(SB)
|
||||
JCS init_avx
|
||||
|
||||
init_x86:
|
||||
CMPQ CX, $0x08
|
||||
JB cmp4
|
||||
MOVQ $0xdfdfdfdfdfdfdfe0, DX
|
||||
MOVQ $0x0101010101010101, BX
|
||||
MOVQ $0x8080808080808080, SI
|
||||
|
||||
cmp8:
|
||||
MOVQ (AX), DI
|
||||
MOVQ DI, R8
|
||||
LEAQ (DI)(DX*1), R9
|
||||
NOTQ R8
|
||||
ANDQ R8, R9
|
||||
LEAQ (DI)(BX*1), R8
|
||||
ORQ R8, DI
|
||||
ORQ R9, DI
|
||||
ADDQ $0x08, AX
|
||||
SUBQ $0x08, CX
|
||||
TESTQ SI, DI
|
||||
JNE done
|
||||
CMPQ CX, $0x08
|
||||
JB cmp4
|
||||
JMP cmp8
|
||||
|
||||
cmp4:
|
||||
CMPQ CX, $0x04
|
||||
JB cmp3
|
||||
MOVL (AX), DX
|
||||
MOVL DX, BX
|
||||
LEAL 3755991008(DX), SI
|
||||
NOTL BX
|
||||
ANDL BX, SI
|
||||
LEAL 16843009(DX), BX
|
||||
ORL BX, DX
|
||||
ORL SI, DX
|
||||
ADDQ $0x04, AX
|
||||
SUBQ $0x04, CX
|
||||
TESTL $0x80808080, DX
|
||||
JNE done
|
||||
|
||||
cmp3:
|
||||
CMPQ CX, $0x03
|
||||
JB cmp2
|
||||
MOVWLZX (AX), DX
|
||||
MOVBLZX 2(AX), AX
|
||||
SHLL $0x10, AX
|
||||
ORL DX, AX
|
||||
ORL $0x20000000, AX
|
||||
JMP final
|
||||
|
||||
cmp2:
|
||||
CMPQ CX, $0x02
|
||||
JB cmp1
|
||||
MOVWLZX (AX), AX
|
||||
ORL $0x20200000, AX
|
||||
JMP final
|
||||
|
||||
cmp1:
|
||||
CMPQ CX, $0x00
|
||||
JE done
|
||||
MOVBLZX (AX), AX
|
||||
ORL $0x20202000, AX
|
||||
|
||||
final:
|
||||
MOVL AX, CX
|
||||
LEAL 3755991008(AX), DX
|
||||
NOTL CX
|
||||
ANDL CX, DX
|
||||
LEAL 16843009(AX), CX
|
||||
ORL CX, AX
|
||||
ORL DX, AX
|
||||
TESTL $0x80808080, AX
|
||||
|
||||
done:
|
||||
SETEQ ret+16(FP)
|
||||
RET
|
||||
|
||||
init_avx:
|
||||
MOVB $0x1f, DL
|
||||
PINSRB $0x00, DX, X8
|
||||
VPBROADCASTB X8, Y8
|
||||
MOVB $0x7e, DL
|
||||
PINSRB $0x00, DX, X9
|
||||
VPBROADCASTB X9, Y9
|
||||
|
||||
cmp128:
|
||||
CMPQ CX, $0x80
|
||||
JB cmp64
|
||||
VMOVDQU (AX), Y0
|
||||
VMOVDQU 32(AX), Y1
|
||||
VMOVDQU 64(AX), Y2
|
||||
VMOVDQU 96(AX), Y3
|
||||
VPCMPGTB Y8, Y0, Y4
|
||||
VPCMPGTB Y9, Y0, Y0
|
||||
VPANDN Y4, Y0, Y0
|
||||
VPCMPGTB Y8, Y1, Y5
|
||||
VPCMPGTB Y9, Y1, Y1
|
||||
VPANDN Y5, Y1, Y1
|
||||
VPCMPGTB Y8, Y2, Y6
|
||||
VPCMPGTB Y9, Y2, Y2
|
||||
VPANDN Y6, Y2, Y2
|
||||
VPCMPGTB Y8, Y3, Y7
|
||||
VPCMPGTB Y9, Y3, Y3
|
||||
VPANDN Y7, Y3, Y3
|
||||
VPAND Y1, Y0, Y0
|
||||
VPAND Y3, Y2, Y2
|
||||
VPAND Y2, Y0, Y0
|
||||
ADDQ $0x80, AX
|
||||
SUBQ $0x80, CX
|
||||
VPMOVMSKB Y0, DX
|
||||
XORL $0xffffffff, DX
|
||||
JNE done
|
||||
JMP cmp128
|
||||
|
||||
cmp64:
|
||||
CMPQ CX, $0x40
|
||||
JB cmp32
|
||||
VMOVDQU (AX), Y0
|
||||
VMOVDQU 32(AX), Y1
|
||||
VPCMPGTB Y8, Y0, Y2
|
||||
VPCMPGTB Y9, Y0, Y0
|
||||
VPANDN Y2, Y0, Y0
|
||||
VPCMPGTB Y8, Y1, Y3
|
||||
VPCMPGTB Y9, Y1, Y1
|
||||
VPANDN Y3, Y1, Y1
|
||||
VPAND Y1, Y0, Y0
|
||||
ADDQ $0x40, AX
|
||||
SUBQ $0x40, CX
|
||||
VPMOVMSKB Y0, DX
|
||||
XORL $0xffffffff, DX
|
||||
JNE done
|
||||
|
||||
cmp32:
|
||||
CMPQ CX, $0x20
|
||||
JB cmp16
|
||||
VMOVDQU (AX), Y0
|
||||
VPCMPGTB Y8, Y0, Y1
|
||||
VPCMPGTB Y9, Y0, Y0
|
||||
VPANDN Y1, Y0, Y0
|
||||
ADDQ $0x20, AX
|
||||
SUBQ $0x20, CX
|
||||
VPMOVMSKB Y0, DX
|
||||
XORL $0xffffffff, DX
|
||||
JNE done
|
||||
|
||||
cmp16:
|
||||
CMPQ CX, $0x10
|
||||
JLE cmp_tail
|
||||
VMOVDQU (AX), X0
|
||||
VPCMPGTB X8, X0, X1
|
||||
VPCMPGTB X9, X0, X0
|
||||
VPANDN X1, X0, X0
|
||||
ADDQ $0x10, AX
|
||||
SUBQ $0x10, CX
|
||||
VPMOVMSKB X0, DX
|
||||
XORL $0x0000ffff, DX
|
||||
JNE done
|
||||
|
||||
cmp_tail:
|
||||
SUBQ $0x10, CX
|
||||
ADDQ CX, AX
|
||||
VMOVDQU (AX), X0
|
||||
VPCMPGTB X8, X0, X1
|
||||
VPCMPGTB X9, X0, X0
|
||||
VPANDN X1, X0, X0
|
||||
VPMOVMSKB X0, DX
|
||||
XORL $0x0000ffff, DX
|
||||
JMP done
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
//go:build purego || !amd64
|
||||
// +build purego !amd64
|
||||
|
||||
package ascii
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// ValidString returns true if s contains only printable ASCII characters.
|
||||
func ValidPrintString(s string) bool {
|
||||
p := *(*unsafe.Pointer)(unsafe.Pointer(&s))
|
||||
i := uintptr(0)
|
||||
n := uintptr(len(s))
|
||||
|
||||
for i+8 <= n {
|
||||
if hasLess64(*(*uint64)(unsafe.Pointer(uintptr(p) + i)), 0x20) || hasMore64(*(*uint64)(unsafe.Pointer(uintptr(p) + i)), 0x7e) {
|
||||
return false
|
||||
}
|
||||
i += 8
|
||||
}
|
||||
|
||||
if i+4 <= n {
|
||||
if hasLess32(*(*uint32)(unsafe.Pointer(uintptr(p) + i)), 0x20) || hasMore32(*(*uint32)(unsafe.Pointer(uintptr(p) + i)), 0x7e) {
|
||||
return false
|
||||
}
|
||||
i += 4
|
||||
}
|
||||
|
||||
if i == n {
|
||||
return true
|
||||
}
|
||||
|
||||
p = unsafe.Pointer(uintptr(p) + i)
|
||||
|
||||
var x uint32
|
||||
switch n - i {
|
||||
case 3:
|
||||
x = 0x20000000 | uint32(*(*uint16)(p)) | uint32(*(*uint8)(unsafe.Pointer(uintptr(p) + 2)))<<16
|
||||
case 2:
|
||||
x = 0x20200000 | uint32(*(*uint16)(p))
|
||||
case 1:
|
||||
x = 0x20202000 | uint32(*(*uint8)(p))
|
||||
default:
|
||||
return true
|
||||
}
|
||||
return !(hasLess32(x, 0x20) || hasMore32(x, 0x7e))
|
||||
}
|
||||
Reference in New Issue
Block a user