github.com/bir3/gocompiler@v0.9.2202/src/internal/bytealg/compare_386.s (about)

     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  #ifdef GO386_softfloat
    40  	JMP	mediumloop
    41  #endif
    42  largeloop:
    43  	CMPL	BP, $16
    44  	JB	mediumloop
    45  	MOVOU	(SI), X0
    46  	MOVOU	(DI), X1
    47  	PCMPEQB X0, X1
    48  	PMOVMSKB X1, BX
    49  	XORL	$0xffff, BX	// convert EQ to NE
    50  	JNE	diff16	// branch if at least one byte is not equal
    51  	ADDL	$16, SI
    52  	ADDL	$16, DI
    53  	SUBL	$16, BP
    54  	JMP	largeloop
    55  
    56  diff16:
    57  	BSFL	BX, BX	// index of first byte that differs
    58  	XORL	DX, DX
    59  	MOVB	(SI)(BX*1), CX
    60  	CMPB	CX, (DI)(BX*1)
    61  	SETHI	DX
    62  	LEAL	-1(DX*2), DX	// convert 1/0 to +1/-1
    63  	MOVL	DX, (AX)
    64  	RET
    65  
    66  mediumloop:
    67  	CMPL	BP, $4
    68  	JBE	_0through4
    69  	MOVL	(SI), BX
    70  	MOVL	(DI), CX
    71  	CMPL	BX, CX
    72  	JNE	diff4
    73  	ADDL	$4, SI
    74  	ADDL	$4, DI
    75  	SUBL	$4, BP
    76  	JMP	mediumloop
    77  
    78  _0through4:
    79  	MOVL	-4(SI)(BP*1), BX
    80  	MOVL	-4(DI)(BP*1), CX
    81  	CMPL	BX, CX
    82  	JEQ	allsame
    83  
    84  diff4:
    85  	BSWAPL	BX	// reverse order of bytes
    86  	BSWAPL	CX
    87  	XORL	BX, CX	// find bit differences
    88  	BSRL	CX, CX	// index of highest bit difference
    89  	SHRL	CX, BX	// move a's bit to bottom
    90  	ANDL	$1, BX	// mask bit
    91  	LEAL	-1(BX*2), BX // 1/0 => +1/-1
    92  	MOVL	BX, (AX)
    93  	RET
    94  
    95  	// 0-3 bytes in common
    96  small:
    97  	LEAL	(BP*8), CX
    98  	NEGL	CX
    99  	JEQ	allsame
   100  
   101  	// load si
   102  	CMPB	SI, $0xfc
   103  	JA	si_high
   104  	MOVL	(SI), SI
   105  	JMP	si_finish
   106  si_high:
   107  	MOVL	-4(SI)(BP*1), SI
   108  	SHRL	CX, SI
   109  si_finish:
   110  	SHLL	CX, SI
   111  
   112  	// same for di
   113  	CMPB	DI, $0xfc
   114  	JA	di_high
   115  	MOVL	(DI), DI
   116  	JMP	di_finish
   117  di_high:
   118  	MOVL	-4(DI)(BP*1), DI
   119  	SHRL	CX, DI
   120  di_finish:
   121  	SHLL	CX, DI
   122  
   123  	BSWAPL	SI	// reverse order of bytes
   124  	BSWAPL	DI
   125  	XORL	SI, DI	// find bit differences
   126  	JEQ	allsame
   127  	BSRL	DI, CX	// index of highest bit difference
   128  	SHRL	CX, SI	// move a's bit to bottom
   129  	ANDL	$1, SI	// mask bit
   130  	LEAL	-1(SI*2), BX // 1/0 => +1/-1
   131  	MOVL	BX, (AX)
   132  	RET
   133  
   134  	// all the bytes in common are the same, so we just need
   135  	// to compare the lengths.
   136  allsame:
   137  	XORL	BX, BX
   138  	XORL	CX, CX
   139  	TESTL	DX, DX
   140  	SETLT	BX	// 1 if alen > blen
   141  	SETEQ	CX	// 1 if alen == blen
   142  	LEAL	-1(CX)(BX*2), BX	// 1,0,-1 result
   143  	MOVL	BX, (AX)
   144  	RET