...

Text file src/pkg/internal/bytealg/compare_386.s

     1	// Copyright 2018 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	#include "go_asm.h"
     6	#include "textflag.h"
     7	
     8	TEXT ·Compare(SB),NOSPLIT,$0-28
     9		MOVL	a_base+0(FP), SI
    10		MOVL	a_len+4(FP), BX
    11		MOVL	b_base+12(FP), DI
    12		MOVL	b_len+16(FP), DX
    13		LEAL	ret+24(FP), AX
    14		JMP	cmpbody<>(SB)
    15	
    16	TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
    17		MOVL	a_base+0(FP), SI
    18		MOVL	a_len+4(FP), BX
    19		MOVL	b_base+8(FP), DI
    20		MOVL	b_len+12(FP), DX
    21		LEAL	ret+16(FP), AX
    22		JMP	cmpbody<>(SB)
    23	
    24	// input:
    25	//   SI = a
    26	//   DI = b
    27	//   BX = alen
    28	//   DX = blen
    29	//   AX = address of return word (set to 1/0/-1)
    30	TEXT cmpbody<>(SB),NOSPLIT,$0-0
    31		MOVL	DX, BP
    32		SUBL	BX, DX // DX = blen-alen
    33		JLE	2(PC)
    34		MOVL	BX, BP // BP = min(alen, blen)
    35		CMPL	SI, DI
    36		JEQ	allsame
    37		CMPL	BP, $4
    38		JB	small
    39		CMPB	internal∕cpu·X86+const_offsetX86HasSSE2(SB), $1
    40		JNE	mediumloop
    41	largeloop:
    42		CMPL	BP, $16
    43		JB	mediumloop
    44		MOVOU	(SI), X0
    45		MOVOU	(DI), X1
    46		PCMPEQB X0, X1
    47		PMOVMSKB X1, BX
    48		XORL	$0xffff, BX	// convert EQ to NE
    49		JNE	diff16	// branch if at least one byte is not equal
    50		ADDL	$16, SI
    51		ADDL	$16, DI
    52		SUBL	$16, BP
    53		JMP	largeloop
    54	
    55	diff16:
    56		BSFL	BX, BX	// index of first byte that differs
    57		XORL	DX, DX
    58		MOVB	(SI)(BX*1), CX
    59		CMPB	CX, (DI)(BX*1)
    60		SETHI	DX
    61		LEAL	-1(DX*2), DX	// convert 1/0 to +1/-1
    62		MOVL	DX, (AX)
    63		RET
    64	
    65	mediumloop:
    66		CMPL	BP, $4
    67		JBE	_0through4
    68		MOVL	(SI), BX
    69		MOVL	(DI), CX
    70		CMPL	BX, CX
    71		JNE	diff4
    72		ADDL	$4, SI
    73		ADDL	$4, DI
    74		SUBL	$4, BP
    75		JMP	mediumloop
    76	
    77	_0through4:
    78		MOVL	-4(SI)(BP*1), BX
    79		MOVL	-4(DI)(BP*1), CX
    80		CMPL	BX, CX
    81		JEQ	allsame
    82	
    83	diff4:
    84		BSWAPL	BX	// reverse order of bytes
    85		BSWAPL	CX
    86		XORL	BX, CX	// find bit differences
    87		BSRL	CX, CX	// index of highest bit difference
    88		SHRL	CX, BX	// move a's bit to bottom
    89		ANDL	$1, BX	// mask bit
    90		LEAL	-1(BX*2), BX // 1/0 => +1/-1
    91		MOVL	BX, (AX)
    92		RET
    93	
    94		// 0-3 bytes in common
    95	small:
    96		LEAL	(BP*8), CX
    97		NEGL	CX
    98		JEQ	allsame
    99	
   100		// load si
   101		CMPB	SI, $0xfc
   102		JA	si_high
   103		MOVL	(SI), SI
   104		JMP	si_finish
   105	si_high:
   106		MOVL	-4(SI)(BP*1), SI
   107		SHRL	CX, SI
   108	si_finish:
   109		SHLL	CX, SI
   110	
   111		// same for di
   112		CMPB	DI, $0xfc
   113		JA	di_high
   114		MOVL	(DI), DI
   115		JMP	di_finish
   116	di_high:
   117		MOVL	-4(DI)(BP*1), DI
   118		SHRL	CX, DI
   119	di_finish:
   120		SHLL	CX, DI
   121	
   122		BSWAPL	SI	// reverse order of bytes
   123		BSWAPL	DI
   124		XORL	SI, DI	// find bit differences
   125		JEQ	allsame
   126		BSRL	DI, CX	// index of highest bit difference
   127		SHRL	CX, SI	// move a's bit to bottom
   128		ANDL	$1, SI	// mask bit
   129		LEAL	-1(SI*2), BX // 1/0 => +1/-1
   130		MOVL	BX, (AX)
   131		RET
   132	
   133		// all the bytes in common are the same, so we just need
   134		// to compare the lengths.
   135	allsame:
   136		XORL	BX, BX
   137		XORL	CX, CX
   138		TESTL	DX, DX
   139		SETLT	BX	// 1 if alen > blen
   140		SETEQ	CX	// 1 if alen == blen
   141		LEAL	-1(CX)(BX*2), BX	// 1,0,-1 result
   142		MOVL	BX, (AX)
   143		RET

View as plain text