gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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)