// 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. TEXT ·IndexByte(SB),7,$0 MOVQ p+0(FP), SI MOVL len+8(FP), BX MOVB b+16(FP), AL MOVQ SI, DI CMPL BX, $16 JLT small // round up to first 16-byte boundary TESTQ $15, SI JZ aligned MOVQ SI, CX ANDQ $~15, CX ADDQ $16, CX // search the beginning SUBQ SI, CX REPN; SCASB JZ success // DI is 16-byte aligned; get ready to search using SSE instructions aligned: // round down to last 16-byte boundary MOVQ BX, R11 ADDQ SI, R11 ANDQ $~15, R11 // shuffle X0 around so that each byte contains c MOVD AX, X0 PUNPCKLBW X0, X0 PUNPCKLBW X0, X0 PSHUFL $0, X0, X0 JMP condition sse: // move the next 16-byte chunk of the buffer into X1 MOVO (DI), X1 // compare bytes in X0 to X1 PCMPEQB X0, X1 // take the top bit of each byte in X1 and put the result in DX PMOVMSKB X1, DX TESTL DX, DX JNZ ssesuccess ADDQ $16, DI condition: CMPQ DI, R11 JLT sse // search the end MOVQ SI, CX ADDQ BX, CX SUBQ R11, CX // if CX == 0, the zero flag will be set and we'll end up // returning a false success JZ failure REPN; SCASB JZ success failure: MOVL $-1, ret+24(FP) RET // handle for lengths < 16 small: MOVL BX, CX REPN; SCASB JZ success MOVL $-1, ret+24(FP) RET // we've found the chunk containing the byte // now just figure out which specific byte it is ssesuccess: // get the index of the least significant set bit BSFW DX, DX SUBQ SI, DI ADDQ DI, DX MOVL DX, ret+24(FP) RET success: SUBQ SI, DI SUBL $1, DI MOVL DI, ret+24(FP) RET