| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- // Copyright 2016 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.
- // +build !appengine
- // +build gc
- // +build !noasm
- #include "textflag.h"
- // The asm code generally follows the pure Go code in encode_other.go, except
- // where marked with a "!!!".
- // func extendMatch(src []byte, i, j int) int
- //
- // All local variables fit into registers. The register allocation:
- // - CX &src[0]
- // - DX &src[len(src)]
- // - SI &src[i]
- // - DI &src[j]
- // - R9 &src[len(src) - 8]
- TEXT ·extendMatch(SB), NOSPLIT, $0-48
- MOVQ src_base+0(FP), CX
- MOVQ src_len+8(FP), DX
- MOVQ i+24(FP), SI
- MOVQ j+32(FP), DI
- ADDQ CX, DX
- ADDQ CX, SI
- ADDQ CX, DI
- MOVQ DX, R9
- SUBQ $8, R9
- cmp8:
- // As long as we are 8 or more bytes before the end of src, we can load and
- // compare 8 bytes at a time. If those 8 bytes are equal, repeat.
- CMPQ DI, R9
- JA cmp1
- MOVQ (SI), AX
- MOVQ (DI), BX
- CMPQ AX, BX
- JNE bsf
- ADDQ $8, SI
- ADDQ $8, DI
- JMP cmp8
- bsf:
- // If those 8 bytes were not equal, XOR the two 8 byte values, and return
- // the index of the first byte that differs. The BSF instruction finds the
- // least significant 1 bit, the amd64 architecture is little-endian, and
- // the shift by 3 converts a bit index to a byte index.
- XORQ AX, BX
- BSFQ BX, BX
- SHRQ $3, BX
- ADDQ BX, DI
- // Convert from &src[ret] to ret.
- SUBQ CX, DI
- MOVQ DI, ret+40(FP)
- RET
- cmp1:
- // In src's tail, compare 1 byte at a time.
- CMPQ DI, DX
- JAE end
- MOVB (SI), AX
- MOVB (DI), BX
- CMPB AX, BX
- JNE end
- ADDQ $1, SI
- ADDQ $1, DI
- JMP cmp1
- end:
- // Convert from &src[ret] to ret.
- SUBQ CX, DI
- MOVQ DI, ret+40(FP)
- RET
|