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"
|
||||
"math/big"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil/asmhex"
|
||||
)
|
||||
|
||||
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.
|
||||
func Decode(input string) ([]byte, error) {
|
||||
// Sanity check the input
|
||||
if len(input) == 0 {
|
||||
return nil, ErrEmptyString
|
||||
}
|
||||
if !has0xPrefix(input) {
|
||||
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 {
|
||||
err = mapError(err)
|
||||
}
|
||||
return b, err
|
||||
return dst, err
|
||||
}
|
||||
|
||||
// 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 {
|
||||
enc := make([]byte, len(b)*2+2)
|
||||
copy(enc, "0x")
|
||||
hex.Encode(enc[2:], b)
|
||||
asmhex.Encode(enc[2:], b)
|
||||
return string(enc)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@
|
|||
package hexutil
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil/asmhex"
|
||||
"github.com/holiman/uint256"
|
||||
)
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ type Bytes []byte
|
|||
func (b Bytes) MarshalText() ([]byte, error) {
|
||||
result := make([]byte, len(b)*2+2)
|
||||
copy(result, `0x`)
|
||||
hex.Encode(result[2:], b)
|
||||
asmhex.Encode(result[2:], b)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ func (b *Bytes) UnmarshalText(input []byte) error {
|
|||
return err
|
||||
}
|
||||
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)
|
||||
} else {
|
||||
*b = dec
|
||||
|
|
@ -121,7 +121,7 @@ func UnmarshalFixedText(typname string, input, out []byte) error {
|
|||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
hex.Decode(out, raw)
|
||||
asmhex.Decode(out, raw)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -142,7 +142,7 @@ func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error {
|
|||
return ErrSyntax
|
||||
}
|
||||
}
|
||||
hex.Decode(out, raw)
|
||||
asmhex.Decode(out, raw)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue