hex_amd64.go (2244B)
1 // Copyright 2016 Tom Thorogood. All rights reserved. 2 // Use of this source code is governed by a 3 // Modified BSD License license that can be found in 4 // the LICENSE file. 5 6 // +build amd64,!gccgo,!appengine 7 8 package hex 9 10 import "golang.org/x/sys/cpu" 11 12 // RawEncode encodes src into EncodedLen(len(src)) 13 // bytes of dst. As a convenience, it returns the number 14 // of bytes written to dst, but this value is always EncodedLen(len(src)). 15 // RawEncode implements hexadecimal encoding for a given alphabet. 16 func RawEncode(dst, src, alpha []byte) int { 17 if len(alpha) != 16 { 18 panic("invalid alphabet") 19 } 20 21 if len(dst) < len(src)*2 { 22 panic("dst buffer is too small") 23 } 24 25 if len(src) == 0 { 26 return 0 27 } 28 29 switch { 30 case cpu.X86.HasAVX: 31 encodeAVX(&dst[0], &src[0], uint64(len(src)), &alpha[0]) 32 case cpu.X86.HasSSE41: 33 encodeSSE(&dst[0], &src[0], uint64(len(src)), &alpha[0]) 34 default: 35 encodeGeneric(dst, src, alpha) 36 } 37 38 return len(src) * 2 39 } 40 41 // Decode decodes src into DecodedLen(len(src)) bytes, returning the actual 42 // number of bytes written to dst. 43 // 44 // If Decode encounters invalid input, it returns an error describing the failure. 45 func Decode(dst, src []byte) (int, error) { 46 if len(src)%2 != 0 { 47 return 0, errLength 48 } 49 50 if len(dst) < len(src)/2 { 51 panic("dst buffer is too small") 52 } 53 54 if len(src) == 0 { 55 return 0, nil 56 } 57 58 var ( 59 n uint64 60 ok bool 61 ) 62 switch { 63 case cpu.X86.HasAVX: 64 n, ok = decodeAVX(&dst[0], &src[0], uint64(len(src))) 65 case cpu.X86.HasSSE41: 66 n, ok = decodeSSE(&dst[0], &src[0], uint64(len(src))) 67 default: 68 n, ok = decodeGeneric(dst, src) 69 } 70 71 if !ok { 72 return 0, InvalidByteError(src[n]) 73 } 74 75 return len(src) / 2, nil 76 } 77 78 //go:generate go run asm_gen.go 79 80 // This function is implemented in hex_encode_amd64.s 81 //go:noescape 82 func encodeAVX(dst *byte, src *byte, len uint64, alpha *byte) 83 84 // This function is implemented in hex_encode_amd64.s 85 //go:noescape 86 func encodeSSE(dst *byte, src *byte, len uint64, alpha *byte) 87 88 // This function is implemented in hex_decode_amd64.s 89 //go:noescape 90 func decodeAVX(dst *byte, src *byte, len uint64) (n uint64, ok bool) 91 92 // This function is implemented in hex_decode_amd64.s 93 //go:noescape 94 func decodeSSE(dst *byte, src *byte, len uint64) (n uint64, ok bool)