mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
common/hexutil: use assembly hex encoder on amd64
This commit is contained in:
parent
9298d2db88
commit
49592effee
9 changed files with 791 additions and 8 deletions
82
common/hexutil/asmhex/LICENSE
Normal file
82
common/hexutil/asmhex/LICENSE
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
Copyright (c) 2016, Tom Thorogood.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the Tom Thorogood nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
---- Portions of the source code are also covered by the following license: ----
|
||||||
|
|
||||||
|
Copyright (c) 2012 The Go Authors. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
---- Portions of the source code are also covered by the following license: ----
|
||||||
|
|
||||||
|
Copyright (c) 2005-2016, Wojciech Muła
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
||||||
|
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
13
common/hexutil/asmhex/asmhex.go
Normal file
13
common/hexutil/asmhex/asmhex.go
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2016 Tom Thorogood. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Modified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
//
|
||||||
|
// Copyright 2009 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 asmhex is an efficient hexadecimal implementation for Golang.
|
||||||
|
package asmhex
|
||||||
|
|
||||||
|
var alphabet = []byte("0123456789abcdef")
|
||||||
80
common/hexutil/asmhex/asmhex_amd64.go
Normal file
80
common/hexutil/asmhex/asmhex_amd64.go
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
// Copyright 2016 Tom Thorogood. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Modified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
|
||||||
|
//go:build amd64 && !gccgo && !appengine
|
||||||
|
|
||||||
|
package asmhex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
|
||||||
|
"golang.org/x/sys/cpu"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Encode(dst, src []byte) int {
|
||||||
|
if len(dst) < len(src)*2 {
|
||||||
|
panic("dst buffer is too small")
|
||||||
|
}
|
||||||
|
if len(src) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case cpu.X86.HasAVX:
|
||||||
|
encodeAVX(&dst[0], &src[0], uint64(len(src)), &alphabet[0])
|
||||||
|
case cpu.X86.HasSSE41:
|
||||||
|
encodeSSE(&dst[0], &src[0], uint64(len(src)), &alphabet[0])
|
||||||
|
default:
|
||||||
|
return hex.Encode(dst, src)
|
||||||
|
}
|
||||||
|
return len(src) * 2
|
||||||
|
}
|
||||||
|
|
||||||
|
func Decode(dst, src []byte) (int, error) {
|
||||||
|
if len(src)%2 != 0 {
|
||||||
|
return 0, hex.ErrLength
|
||||||
|
}
|
||||||
|
if len(dst) < len(src)/2 {
|
||||||
|
panic("dst buffer is too small")
|
||||||
|
}
|
||||||
|
if len(src) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
var (
|
||||||
|
n uint64
|
||||||
|
ok bool
|
||||||
|
)
|
||||||
|
switch {
|
||||||
|
case cpu.X86.HasAVX:
|
||||||
|
n, ok = decodeAVX(&dst[0], &src[0], uint64(len(src)))
|
||||||
|
case cpu.X86.HasSSE41:
|
||||||
|
n, ok = decodeSSE(&dst[0], &src[0], uint64(len(src)))
|
||||||
|
default:
|
||||||
|
return hex.Decode(dst, src)
|
||||||
|
}
|
||||||
|
if !ok {
|
||||||
|
return 0, hex.InvalidByteError(src[n])
|
||||||
|
}
|
||||||
|
return len(src) / 2, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is implemented in asmhex_encode_amd64.s
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func encodeAVX(dst *byte, src *byte, len uint64, alpha *byte)
|
||||||
|
|
||||||
|
// This function is implemented in asmhex_encode_amd64.s
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func encodeSSE(dst *byte, src *byte, len uint64, alpha *byte)
|
||||||
|
|
||||||
|
// This function is implemented in asmhex_decode_amd64.s
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func decodeAVX(dst *byte, src *byte, len uint64) (n uint64, ok bool)
|
||||||
|
|
||||||
|
// This function is implemented in asmhex_decode_amd64.s
|
||||||
|
//
|
||||||
|
//go:noescape
|
||||||
|
func decodeSSE(dst *byte, src *byte, len uint64) (n uint64, ok bool)
|
||||||
303
common/hexutil/asmhex/asmhex_decode_amd64.s
Normal file
303
common/hexutil/asmhex/asmhex_decode_amd64.s
Normal file
|
|
@ -0,0 +1,303 @@
|
||||||
|
// Copyright 2016 Tom Thorogood. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Modified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
//
|
||||||
|
// Copyright 2005-2016, Wojciech Muła. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Simplified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
//
|
||||||
|
// This file is auto-generated - do not modify
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
DATA decodeBase<>+0x00(SB)/8, $0x3030303030303030
|
||||||
|
DATA decodeBase<>+0x08(SB)/8, $0x3030303030303030
|
||||||
|
DATA decodeBase<>+0x10(SB)/8, $0x2727272727272727
|
||||||
|
DATA decodeBase<>+0x18(SB)/8, $0x2727272727272727
|
||||||
|
GLOBL decodeBase<>(SB),RODATA,$32
|
||||||
|
|
||||||
|
DATA decodeToLower<>+0x00(SB)/8, $0x2020202020202020
|
||||||
|
DATA decodeToLower<>+0x08(SB)/8, $0x2020202020202020
|
||||||
|
GLOBL decodeToLower<>(SB),RODATA,$16
|
||||||
|
|
||||||
|
DATA decodeHigh<>+0x00(SB)/8, $0x0e0c0a0806040200
|
||||||
|
DATA decodeHigh<>+0x08(SB)/8, $0xffffffffffffffff
|
||||||
|
GLOBL decodeHigh<>(SB),RODATA,$16
|
||||||
|
|
||||||
|
DATA decodeLow<>+0x00(SB)/8, $0x0f0d0b0907050301
|
||||||
|
DATA decodeLow<>+0x08(SB)/8, $0xffffffffffffffff
|
||||||
|
GLOBL decodeLow<>(SB),RODATA,$16
|
||||||
|
|
||||||
|
DATA decodeValid<>+0x00(SB)/8, $0xb0b0b0b0b0b0b0b0
|
||||||
|
DATA decodeValid<>+0x08(SB)/8, $0xb0b0b0b0b0b0b0b0
|
||||||
|
DATA decodeValid<>+0x10(SB)/8, $0xb9b9b9b9b9b9b9b9
|
||||||
|
DATA decodeValid<>+0x18(SB)/8, $0xb9b9b9b9b9b9b9b9
|
||||||
|
DATA decodeValid<>+0x20(SB)/8, $0xe1e1e1e1e1e1e1e1
|
||||||
|
DATA decodeValid<>+0x28(SB)/8, $0xe1e1e1e1e1e1e1e1
|
||||||
|
DATA decodeValid<>+0x30(SB)/8, $0xe6e6e6e6e6e6e6e6
|
||||||
|
DATA decodeValid<>+0x38(SB)/8, $0xe6e6e6e6e6e6e6e6
|
||||||
|
GLOBL decodeValid<>(SB),RODATA,$64
|
||||||
|
|
||||||
|
DATA decodeToSigned<>+0x00(SB)/8, $0x8080808080808080
|
||||||
|
DATA decodeToSigned<>+0x08(SB)/8, $0x8080808080808080
|
||||||
|
GLOBL decodeToSigned<>(SB),RODATA,$16
|
||||||
|
|
||||||
|
TEXT ·decodeAVX(SB),NOSPLIT,$0
|
||||||
|
MOVQ dst+0(FP), DI
|
||||||
|
MOVQ src+8(FP), SI
|
||||||
|
MOVQ len+16(FP), BX
|
||||||
|
MOVQ SI, R15
|
||||||
|
MOVOU decodeValid<>(SB), X14
|
||||||
|
MOVOU decodeValid<>+0x20(SB), X15
|
||||||
|
MOVW $65535, DX
|
||||||
|
CMPQ BX, $16
|
||||||
|
JB tail
|
||||||
|
bigloop:
|
||||||
|
MOVOU (SI), X0
|
||||||
|
VPXOR decodeToSigned<>(SB), X0, X1
|
||||||
|
POR decodeToLower<>(SB), X0
|
||||||
|
VPXOR decodeToSigned<>(SB), X0, X2
|
||||||
|
VPCMPGTB X1, X14, X3
|
||||||
|
PCMPGTB decodeValid<>+0x10(SB), X1
|
||||||
|
VPCMPGTB X2, X15, X4
|
||||||
|
PCMPGTB decodeValid<>+0x30(SB), X2
|
||||||
|
PAND X4, X1
|
||||||
|
POR X2, X3
|
||||||
|
POR X1, X3
|
||||||
|
PMOVMSKB X3, AX
|
||||||
|
TESTW AX, DX
|
||||||
|
JNZ invalid
|
||||||
|
PSUBB decodeBase<>(SB), X0
|
||||||
|
PANDN decodeBase<>+0x10(SB), X4
|
||||||
|
PSUBB X4, X0
|
||||||
|
VPSHUFB decodeLow<>(SB), X0, X3
|
||||||
|
PSHUFB decodeHigh<>(SB), X0
|
||||||
|
PSLLW $4, X0
|
||||||
|
POR X3, X0
|
||||||
|
MOVQ X0, (DI)
|
||||||
|
SUBQ $16, BX
|
||||||
|
JZ ret
|
||||||
|
ADDQ $16, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
CMPQ BX, $16
|
||||||
|
JAE bigloop
|
||||||
|
tail:
|
||||||
|
MOVQ $16, CX
|
||||||
|
SUBQ BX, CX
|
||||||
|
SHRW CX, DX
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_in_2
|
||||||
|
JE tail_in_4
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_in_6
|
||||||
|
JE tail_in_8
|
||||||
|
CMPQ BX, $12
|
||||||
|
JB tail_in_10
|
||||||
|
JE tail_in_12
|
||||||
|
tail_in_14:
|
||||||
|
PINSRW $6, 12(SI), X0
|
||||||
|
tail_in_12:
|
||||||
|
PINSRW $5, 10(SI), X0
|
||||||
|
tail_in_10:
|
||||||
|
PINSRW $4, 8(SI), X0
|
||||||
|
tail_in_8:
|
||||||
|
PINSRQ $0, (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_6:
|
||||||
|
PINSRW $2, 4(SI), X0
|
||||||
|
tail_in_4:
|
||||||
|
PINSRW $1, 2(SI), X0
|
||||||
|
tail_in_2:
|
||||||
|
PINSRW $0, (SI), X0
|
||||||
|
tail_conv:
|
||||||
|
VPXOR decodeToSigned<>(SB), X0, X1
|
||||||
|
POR decodeToLower<>(SB), X0
|
||||||
|
VPXOR decodeToSigned<>(SB), X0, X2
|
||||||
|
VPCMPGTB X1, X14, X3
|
||||||
|
PCMPGTB decodeValid<>+0x10(SB), X1
|
||||||
|
VPCMPGTB X2, X15, X4
|
||||||
|
PCMPGTB decodeValid<>+0x30(SB), X2
|
||||||
|
PAND X4, X1
|
||||||
|
POR X2, X3
|
||||||
|
POR X1, X3
|
||||||
|
PMOVMSKB X3, AX
|
||||||
|
TESTW AX, DX
|
||||||
|
JNZ invalid
|
||||||
|
PSUBB decodeBase<>(SB), X0
|
||||||
|
PANDN decodeBase<>+0x10(SB), X4
|
||||||
|
PSUBB X4, X0
|
||||||
|
VPSHUFB decodeLow<>(SB), X0, X3
|
||||||
|
PSHUFB decodeHigh<>(SB), X0
|
||||||
|
PSLLW $4, X0
|
||||||
|
POR X3, X0
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_out_2
|
||||||
|
JE tail_out_4
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_out_6
|
||||||
|
JE tail_out_8
|
||||||
|
CMPQ BX, $12
|
||||||
|
JB tail_out_10
|
||||||
|
JE tail_out_12
|
||||||
|
tail_out_14:
|
||||||
|
PEXTRB $6, X0, 6(DI)
|
||||||
|
tail_out_12:
|
||||||
|
PEXTRB $5, X0, 5(DI)
|
||||||
|
tail_out_10:
|
||||||
|
PEXTRB $4, X0, 4(DI)
|
||||||
|
tail_out_8:
|
||||||
|
MOVL X0, (DI)
|
||||||
|
JMP ret
|
||||||
|
tail_out_6:
|
||||||
|
PEXTRB $2, X0, 2(DI)
|
||||||
|
tail_out_4:
|
||||||
|
PEXTRB $1, X0, 1(DI)
|
||||||
|
tail_out_2:
|
||||||
|
PEXTRB $0, X0, (DI)
|
||||||
|
ret:
|
||||||
|
MOVB $1, ok+32(FP)
|
||||||
|
RET
|
||||||
|
invalid:
|
||||||
|
BSFW AX, AX
|
||||||
|
SUBQ R15, SI
|
||||||
|
ADDQ SI, AX
|
||||||
|
MOVQ AX, n+24(FP)
|
||||||
|
MOVB $0, ok+32(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·decodeSSE(SB),NOSPLIT,$0
|
||||||
|
MOVQ dst+0(FP), DI
|
||||||
|
MOVQ src+8(FP), SI
|
||||||
|
MOVQ len+16(FP), BX
|
||||||
|
MOVQ SI, R15
|
||||||
|
MOVOU decodeValid<>(SB), X14
|
||||||
|
MOVOU decodeValid<>+0x20(SB), X15
|
||||||
|
MOVW $65535, DX
|
||||||
|
CMPQ BX, $16
|
||||||
|
JB tail
|
||||||
|
bigloop:
|
||||||
|
MOVOU (SI), X0
|
||||||
|
MOVOU X0, X1
|
||||||
|
PXOR decodeToSigned<>(SB), X1
|
||||||
|
POR decodeToLower<>(SB), X0
|
||||||
|
MOVOU X0, X2
|
||||||
|
PXOR decodeToSigned<>(SB), X2
|
||||||
|
MOVOU X14, X3
|
||||||
|
PCMPGTB X1, X3
|
||||||
|
PCMPGTB decodeValid<>+0x10(SB), X1
|
||||||
|
MOVOU X15, X4
|
||||||
|
PCMPGTB X2, X4
|
||||||
|
PCMPGTB decodeValid<>+0x30(SB), X2
|
||||||
|
PAND X4, X1
|
||||||
|
POR X2, X3
|
||||||
|
POR X1, X3
|
||||||
|
PMOVMSKB X3, AX
|
||||||
|
TESTW AX, DX
|
||||||
|
JNZ invalid
|
||||||
|
PSUBB decodeBase<>(SB), X0
|
||||||
|
PANDN decodeBase<>+0x10(SB), X4
|
||||||
|
PSUBB X4, X0
|
||||||
|
MOVOU X0, X3
|
||||||
|
PSHUFB decodeLow<>(SB), X3
|
||||||
|
PSHUFB decodeHigh<>(SB), X0
|
||||||
|
PSLLW $4, X0
|
||||||
|
POR X3, X0
|
||||||
|
MOVQ X0, (DI)
|
||||||
|
SUBQ $16, BX
|
||||||
|
JZ ret
|
||||||
|
ADDQ $16, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
CMPQ BX, $16
|
||||||
|
JAE bigloop
|
||||||
|
tail:
|
||||||
|
MOVQ $16, CX
|
||||||
|
SUBQ BX, CX
|
||||||
|
SHRW CX, DX
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_in_2
|
||||||
|
JE tail_in_4
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_in_6
|
||||||
|
JE tail_in_8
|
||||||
|
CMPQ BX, $12
|
||||||
|
JB tail_in_10
|
||||||
|
JE tail_in_12
|
||||||
|
tail_in_14:
|
||||||
|
PINSRW $6, 12(SI), X0
|
||||||
|
tail_in_12:
|
||||||
|
PINSRW $5, 10(SI), X0
|
||||||
|
tail_in_10:
|
||||||
|
PINSRW $4, 8(SI), X0
|
||||||
|
tail_in_8:
|
||||||
|
PINSRQ $0, (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_6:
|
||||||
|
PINSRW $2, 4(SI), X0
|
||||||
|
tail_in_4:
|
||||||
|
PINSRW $1, 2(SI), X0
|
||||||
|
tail_in_2:
|
||||||
|
PINSRW $0, (SI), X0
|
||||||
|
tail_conv:
|
||||||
|
MOVOU X0, X1
|
||||||
|
PXOR decodeToSigned<>(SB), X1
|
||||||
|
POR decodeToLower<>(SB), X0
|
||||||
|
MOVOU X0, X2
|
||||||
|
PXOR decodeToSigned<>(SB), X2
|
||||||
|
MOVOU X14, X3
|
||||||
|
PCMPGTB X1, X3
|
||||||
|
PCMPGTB decodeValid<>+0x10(SB), X1
|
||||||
|
MOVOU X15, X4
|
||||||
|
PCMPGTB X2, X4
|
||||||
|
PCMPGTB decodeValid<>+0x30(SB), X2
|
||||||
|
PAND X4, X1
|
||||||
|
POR X2, X3
|
||||||
|
POR X1, X3
|
||||||
|
PMOVMSKB X3, AX
|
||||||
|
TESTW AX, DX
|
||||||
|
JNZ invalid
|
||||||
|
PSUBB decodeBase<>(SB), X0
|
||||||
|
PANDN decodeBase<>+0x10(SB), X4
|
||||||
|
PSUBB X4, X0
|
||||||
|
MOVOU X0, X3
|
||||||
|
PSHUFB decodeLow<>(SB), X3
|
||||||
|
PSHUFB decodeHigh<>(SB), X0
|
||||||
|
PSLLW $4, X0
|
||||||
|
POR X3, X0
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_out_2
|
||||||
|
JE tail_out_4
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_out_6
|
||||||
|
JE tail_out_8
|
||||||
|
CMPQ BX, $12
|
||||||
|
JB tail_out_10
|
||||||
|
JE tail_out_12
|
||||||
|
tail_out_14:
|
||||||
|
PEXTRB $6, X0, 6(DI)
|
||||||
|
tail_out_12:
|
||||||
|
PEXTRB $5, X0, 5(DI)
|
||||||
|
tail_out_10:
|
||||||
|
PEXTRB $4, X0, 4(DI)
|
||||||
|
tail_out_8:
|
||||||
|
MOVL X0, (DI)
|
||||||
|
JMP ret
|
||||||
|
tail_out_6:
|
||||||
|
PEXTRB $2, X0, 2(DI)
|
||||||
|
tail_out_4:
|
||||||
|
PEXTRB $1, X0, 1(DI)
|
||||||
|
tail_out_2:
|
||||||
|
PEXTRB $0, X0, (DI)
|
||||||
|
ret:
|
||||||
|
MOVB $1, ok+32(FP)
|
||||||
|
RET
|
||||||
|
invalid:
|
||||||
|
BSFW AX, AX
|
||||||
|
SUBQ R15, SI
|
||||||
|
ADDQ SI, AX
|
||||||
|
MOVQ AX, n+24(FP)
|
||||||
|
MOVB $0, ok+32(FP)
|
||||||
|
RET
|
||||||
227
common/hexutil/asmhex/asmhex_encode_amd64.s
Normal file
227
common/hexutil/asmhex/asmhex_encode_amd64.s
Normal file
|
|
@ -0,0 +1,227 @@
|
||||||
|
// Copyright 2016 Tom Thorogood. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Modified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
//
|
||||||
|
// Copyright 2005-2016, Wojciech Muła. All rights reserved.
|
||||||
|
// Use of this source code is governed by a
|
||||||
|
// Simplified BSD License license that can be found in
|
||||||
|
// the LICENSE file.
|
||||||
|
//
|
||||||
|
// This file is auto-generated - do not modify
|
||||||
|
|
||||||
|
// +build amd64,!gccgo,!appengine
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
DATA encodeMask<>+0x00(SB)/8, $0x0f0f0f0f0f0f0f0f
|
||||||
|
DATA encodeMask<>+0x08(SB)/8, $0x0f0f0f0f0f0f0f0f
|
||||||
|
GLOBL encodeMask<>(SB),RODATA,$16
|
||||||
|
|
||||||
|
TEXT ·encodeAVX(SB),NOSPLIT,$0
|
||||||
|
MOVQ dst+0(FP), DI
|
||||||
|
MOVQ src+8(FP), SI
|
||||||
|
MOVQ len+16(FP), BX
|
||||||
|
MOVQ alpha+24(FP), DX
|
||||||
|
MOVOU (DX), X15
|
||||||
|
CMPQ BX, $16
|
||||||
|
JB tail
|
||||||
|
bigloop:
|
||||||
|
MOVOU -16(SI)(BX*1), X0
|
||||||
|
VPAND encodeMask<>(SB), X0, X1
|
||||||
|
PSRLW $4, X0
|
||||||
|
PAND encodeMask<>(SB), X0
|
||||||
|
VPUNPCKHBW X1, X0, X3
|
||||||
|
PUNPCKLBW X1, X0
|
||||||
|
VPSHUFB X0, X15, X1
|
||||||
|
VPSHUFB X3, X15, X2
|
||||||
|
MOVOU X2, -16(DI)(BX*2)
|
||||||
|
MOVOU X1, -32(DI)(BX*2)
|
||||||
|
SUBQ $16, BX
|
||||||
|
JZ ret
|
||||||
|
CMPQ BX, $16
|
||||||
|
JAE bigloop
|
||||||
|
tail:
|
||||||
|
CMPQ BX, $2
|
||||||
|
JB tail_in_1
|
||||||
|
JE tail_in_2
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_in_3
|
||||||
|
JE tail_in_4
|
||||||
|
CMPQ BX, $6
|
||||||
|
JB tail_in_5
|
||||||
|
JE tail_in_6
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_in_7
|
||||||
|
tail_in_8:
|
||||||
|
MOVQ (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_7:
|
||||||
|
PINSRB $6, 6(SI), X0
|
||||||
|
tail_in_6:
|
||||||
|
PINSRB $5, 5(SI), X0
|
||||||
|
tail_in_5:
|
||||||
|
PINSRB $4, 4(SI), X0
|
||||||
|
tail_in_4:
|
||||||
|
PINSRD $0, (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_3:
|
||||||
|
PINSRB $2, 2(SI), X0
|
||||||
|
tail_in_2:
|
||||||
|
PINSRB $1, 1(SI), X0
|
||||||
|
tail_in_1:
|
||||||
|
PINSRB $0, (SI), X0
|
||||||
|
tail_conv:
|
||||||
|
VPAND encodeMask<>(SB), X0, X1
|
||||||
|
PSRLW $4, X0
|
||||||
|
PAND encodeMask<>(SB), X0
|
||||||
|
PUNPCKLBW X1, X0
|
||||||
|
VPSHUFB X0, X15, X1
|
||||||
|
CMPQ BX, $2
|
||||||
|
JB tail_out_1
|
||||||
|
JE tail_out_2
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_out_3
|
||||||
|
JE tail_out_4
|
||||||
|
CMPQ BX, $6
|
||||||
|
JB tail_out_5
|
||||||
|
JE tail_out_6
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_out_7
|
||||||
|
tail_out_8:
|
||||||
|
MOVOU X1, (DI)
|
||||||
|
SUBQ $8, BX
|
||||||
|
JZ ret
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $16, DI
|
||||||
|
JMP tail
|
||||||
|
tail_out_7:
|
||||||
|
PEXTRB $13, X1, 13(DI)
|
||||||
|
PEXTRB $12, X1, 12(DI)
|
||||||
|
tail_out_6:
|
||||||
|
PEXTRB $11, X1, 11(DI)
|
||||||
|
PEXTRB $10, X1, 10(DI)
|
||||||
|
tail_out_5:
|
||||||
|
PEXTRB $9, X1, 9(DI)
|
||||||
|
PEXTRB $8, X1, 8(DI)
|
||||||
|
tail_out_4:
|
||||||
|
MOVQ X1, (DI)
|
||||||
|
RET
|
||||||
|
tail_out_3:
|
||||||
|
PEXTRB $5, X1, 5(DI)
|
||||||
|
PEXTRB $4, X1, 4(DI)
|
||||||
|
tail_out_2:
|
||||||
|
PEXTRB $3, X1, 3(DI)
|
||||||
|
PEXTRB $2, X1, 2(DI)
|
||||||
|
tail_out_1:
|
||||||
|
PEXTRB $1, X1, 1(DI)
|
||||||
|
PEXTRB $0, X1, (DI)
|
||||||
|
ret:
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·encodeSSE(SB),NOSPLIT,$0
|
||||||
|
MOVQ dst+0(FP), DI
|
||||||
|
MOVQ src+8(FP), SI
|
||||||
|
MOVQ len+16(FP), BX
|
||||||
|
MOVQ alpha+24(FP), DX
|
||||||
|
MOVOU (DX), X15
|
||||||
|
CMPQ BX, $16
|
||||||
|
JB tail
|
||||||
|
bigloop:
|
||||||
|
MOVOU -16(SI)(BX*1), X0
|
||||||
|
MOVOU X0, X1
|
||||||
|
PAND encodeMask<>(SB), X1
|
||||||
|
PSRLW $4, X0
|
||||||
|
PAND encodeMask<>(SB), X0
|
||||||
|
MOVOU X0, X3
|
||||||
|
PUNPCKHBW X1, X3
|
||||||
|
PUNPCKLBW X1, X0
|
||||||
|
MOVOU X15, X1
|
||||||
|
PSHUFB X0, X1
|
||||||
|
MOVOU X15, X2
|
||||||
|
PSHUFB X3, X2
|
||||||
|
MOVOU X2, -16(DI)(BX*2)
|
||||||
|
MOVOU X1, -32(DI)(BX*2)
|
||||||
|
SUBQ $16, BX
|
||||||
|
JZ ret
|
||||||
|
CMPQ BX, $16
|
||||||
|
JAE bigloop
|
||||||
|
tail:
|
||||||
|
CMPQ BX, $2
|
||||||
|
JB tail_in_1
|
||||||
|
JE tail_in_2
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_in_3
|
||||||
|
JE tail_in_4
|
||||||
|
CMPQ BX, $6
|
||||||
|
JB tail_in_5
|
||||||
|
JE tail_in_6
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_in_7
|
||||||
|
tail_in_8:
|
||||||
|
MOVQ (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_7:
|
||||||
|
PINSRB $6, 6(SI), X0
|
||||||
|
tail_in_6:
|
||||||
|
PINSRB $5, 5(SI), X0
|
||||||
|
tail_in_5:
|
||||||
|
PINSRB $4, 4(SI), X0
|
||||||
|
tail_in_4:
|
||||||
|
PINSRD $0, (SI), X0
|
||||||
|
JMP tail_conv
|
||||||
|
tail_in_3:
|
||||||
|
PINSRB $2, 2(SI), X0
|
||||||
|
tail_in_2:
|
||||||
|
PINSRB $1, 1(SI), X0
|
||||||
|
tail_in_1:
|
||||||
|
PINSRB $0, (SI), X0
|
||||||
|
tail_conv:
|
||||||
|
MOVOU X0, X1
|
||||||
|
PAND encodeMask<>(SB), X1
|
||||||
|
PSRLW $4, X0
|
||||||
|
PAND encodeMask<>(SB), X0
|
||||||
|
PUNPCKLBW X1, X0
|
||||||
|
MOVOU X15, X1
|
||||||
|
PSHUFB X0, X1
|
||||||
|
CMPQ BX, $2
|
||||||
|
JB tail_out_1
|
||||||
|
JE tail_out_2
|
||||||
|
CMPQ BX, $4
|
||||||
|
JB tail_out_3
|
||||||
|
JE tail_out_4
|
||||||
|
CMPQ BX, $6
|
||||||
|
JB tail_out_5
|
||||||
|
JE tail_out_6
|
||||||
|
CMPQ BX, $8
|
||||||
|
JB tail_out_7
|
||||||
|
tail_out_8:
|
||||||
|
MOVOU X1, (DI)
|
||||||
|
SUBQ $8, BX
|
||||||
|
JZ ret
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $16, DI
|
||||||
|
JMP tail
|
||||||
|
tail_out_7:
|
||||||
|
PEXTRB $13, X1, 13(DI)
|
||||||
|
PEXTRB $12, X1, 12(DI)
|
||||||
|
tail_out_6:
|
||||||
|
PEXTRB $11, X1, 11(DI)
|
||||||
|
PEXTRB $10, X1, 10(DI)
|
||||||
|
tail_out_5:
|
||||||
|
PEXTRB $9, X1, 9(DI)
|
||||||
|
PEXTRB $8, X1, 8(DI)
|
||||||
|
tail_out_4:
|
||||||
|
MOVQ X1, (DI)
|
||||||
|
RET
|
||||||
|
tail_out_3:
|
||||||
|
PEXTRB $5, X1, 5(DI)
|
||||||
|
PEXTRB $4, X1, 4(DI)
|
||||||
|
tail_out_2:
|
||||||
|
PEXTRB $3, X1, 3(DI)
|
||||||
|
PEXTRB $2, X1, 2(DI)
|
||||||
|
tail_out_1:
|
||||||
|
PEXTRB $1, X1, 1(DI)
|
||||||
|
PEXTRB $0, X1, (DI)
|
||||||
|
ret:
|
||||||
|
RET
|
||||||
17
common/hexutil/asmhex/asmhex_other.go
Normal file
17
common/hexutil/asmhex/asmhex_other.go
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2009 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.
|
||||||
|
|
||||||
|
//go:build !amd64 || gccgo || appengine
|
||||||
|
|
||||||
|
package asmhex
|
||||||
|
|
||||||
|
import "encoding/hex"
|
||||||
|
|
||||||
|
func Encode(dst, src []byte) int {
|
||||||
|
return hex.Encode(dst, src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Decode(dst, src []byte) (int, error) {
|
||||||
|
return hex.Decode(dst, src)
|
||||||
|
}
|
||||||
54
common/hexutil/asmhex/asmhex_test.go
Normal file
54
common/hexutil/asmhex/asmhex_test.go
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2024 The go-ethereum Authors
|
||||||
|
// This file is part of the go-ethereum library.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// The go-ethereum library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Lesser General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Lesser General Public License
|
||||||
|
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package asmhex
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkAsmHexDecode(b *testing.B) {
|
||||||
|
for _, size := range []int{64, 256, 1024, 4096, 16384, 65536} {
|
||||||
|
src := bytes.Repeat([]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'B', 'c', 'D', 'e', 'f'}, size/8)
|
||||||
|
sink := make([]byte, size)
|
||||||
|
|
||||||
|
b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := Decode(sink, src); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkStdlibDecode(b *testing.B) {
|
||||||
|
for _, size := range []int{64, 256, 1024, 4096, 16384, 65536} {
|
||||||
|
src := bytes.Repeat([]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'B', 'c', 'D', 'e', 'f'}, size/8)
|
||||||
|
sink := make([]byte, size)
|
||||||
|
|
||||||
|
b.Run(fmt.Sprintf("%v", size), func(b *testing.B) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := hex.Decode(sink, src); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,6 +35,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil/asmhex"
|
||||||
)
|
)
|
||||||
|
|
||||||
const uintBits = 32 << (uint64(^uint(0)) >> 63)
|
const uintBits = 32 << (uint64(^uint(0)) >> 63)
|
||||||
|
|
@ -58,17 +60,22 @@ func (err decError) Error() string { return err.msg }
|
||||||
|
|
||||||
// Decode decodes a hex string with 0x prefix.
|
// Decode decodes a hex string with 0x prefix.
|
||||||
func Decode(input string) ([]byte, error) {
|
func Decode(input string) ([]byte, error) {
|
||||||
|
// Sanity check the input
|
||||||
if len(input) == 0 {
|
if len(input) == 0 {
|
||||||
return nil, ErrEmptyString
|
return nil, ErrEmptyString
|
||||||
}
|
}
|
||||||
if !has0xPrefix(input) {
|
if !has0xPrefix(input) {
|
||||||
return nil, ErrMissingPrefix
|
return nil, ErrMissingPrefix
|
||||||
}
|
}
|
||||||
b, err := hex.DecodeString(input[2:])
|
// Preallocate the output and decode the string
|
||||||
|
src := ([]byte)(input)[2:]
|
||||||
|
dst := make([]byte, len(src)>>1)
|
||||||
|
|
||||||
|
_, err := asmhex.Decode(dst, src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = mapError(err)
|
err = mapError(err)
|
||||||
}
|
}
|
||||||
return b, err
|
return dst, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// MustDecode decodes a hex string with 0x prefix. It panics for invalid input.
|
// MustDecode decodes a hex string with 0x prefix. It panics for invalid input.
|
||||||
|
|
@ -84,7 +91,7 @@ func MustDecode(input string) []byte {
|
||||||
func Encode(b []byte) string {
|
func Encode(b []byte) string {
|
||||||
enc := make([]byte, len(b)*2+2)
|
enc := make([]byte, len(b)*2+2)
|
||||||
copy(enc, "0x")
|
copy(enc, "0x")
|
||||||
hex.Encode(enc[2:], b)
|
asmhex.Encode(enc[2:], b)
|
||||||
return string(enc)
|
return string(enc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@
|
||||||
package hexutil
|
package hexutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common/hexutil/asmhex"
|
||||||
"github.com/holiman/uint256"
|
"github.com/holiman/uint256"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ type Bytes []byte
|
||||||
func (b Bytes) MarshalText() ([]byte, error) {
|
func (b Bytes) MarshalText() ([]byte, error) {
|
||||||
result := make([]byte, len(b)*2+2)
|
result := make([]byte, len(b)*2+2)
|
||||||
copy(result, `0x`)
|
copy(result, `0x`)
|
||||||
hex.Encode(result[2:], b)
|
asmhex.Encode(result[2:], b)
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ func (b *Bytes) UnmarshalText(input []byte) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dec := make([]byte, len(raw)/2)
|
dec := make([]byte, len(raw)/2)
|
||||||
if _, err = hex.Decode(dec, raw); err != nil {
|
if _, err = asmhex.Decode(dec, raw); err != nil {
|
||||||
err = mapError(err)
|
err = mapError(err)
|
||||||
} else {
|
} else {
|
||||||
*b = dec
|
*b = dec
|
||||||
|
|
@ -121,7 +121,7 @@ func UnmarshalFixedText(typname string, input, out []byte) error {
|
||||||
return ErrSyntax
|
return ErrSyntax
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hex.Decode(out, raw)
|
asmhex.Decode(out, raw)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,7 +142,7 @@ func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
|
||||||
return ErrSyntax
|
return ErrSyntax
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hex.Decode(out, raw)
|
asmhex.Decode(out, raw)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue