// Copyright 2018 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. #include "go_asm.h" #include "textflag.h" TEXT ·Compare(SB),NOSPLIT,$0-28 MOVL a_base+0(FP), SI MOVL a_len+4(FP), BX MOVL b_base+12(FP), DI MOVL b_len+16(FP), DX LEAL ret+24(FP), AX JMP cmpbody<>(SB) TEXT runtime·cmpstring(SB),NOSPLIT,$0-20 MOVL a_base+0(FP), SI MOVL a_len+4(FP), BX MOVL b_base+8(FP), DI MOVL b_len+12(FP), DX LEAL ret+16(FP), AX JMP cmpbody<>(SB) // input: // SI = a // DI = b // BX = alen // DX = blen // AX = address of return word (set to 1/0/-1) TEXT cmpbody<>(SB),NOSPLIT,$0-0 MOVL DX, BP SUBL BX, DX // DX = blen-alen JLE 2(PC) MOVL BX, BP // BP = min(alen, blen) CMPL SI, DI JEQ allsame CMPL BP, $4 JB small #ifdef GO386_softfloat JMP mediumloop #endif largeloop: CMPL BP, $16 JB mediumloop MOVOU (SI), X0 MOVOU (DI), X1 PCMPEQB X0, X1 PMOVMSKB X1, BX XORL $0xffff, BX // convert EQ to NE JNE diff16 // branch if at least one byte is not equal ADDL $16, SI ADDL $16, DI SUBL $16, BP JMP largeloop diff16: BSFL BX, BX // index of first byte that differs XORL DX, DX MOVB (SI)(BX*1), CX CMPB CX, (DI)(BX*1) SETHI DX LEAL -1(DX*2), DX // convert 1/0 to +1/-1 MOVL DX, (AX) RET mediumloop: CMPL BP, $4 JBE _0through4 MOVL (SI), BX MOVL (DI), CX CMPL BX, CX JNE diff4 ADDL $4, SI ADDL $4, DI SUBL $4, BP JMP mediumloop _0through4: MOVL -4(SI)(BP*1), BX MOVL -4(DI)(BP*1), CX CMPL BX, CX JEQ allsame diff4: BSWAPL BX // reverse order of bytes BSWAPL CX XORL BX, CX // find bit differences BSRL CX, CX // index of highest bit difference SHRL CX, BX // move a's bit to bottom ANDL $1, BX // mask bit LEAL -1(BX*2), BX // 1/0 => +1/-1 MOVL BX, (AX) RET // 0-3 bytes in common small: LEAL (BP*8), CX NEGL CX JEQ allsame // load si CMPB SI, $0xfc JA si_high MOVL (SI), SI JMP si_finish si_high: MOVL -4(SI)(BP*1), SI SHRL CX, SI si_finish: SHLL CX, SI // same for di CMPB DI, $0xfc JA di_high MOVL (DI), DI JMP di_finish di_high: MOVL -4(DI)(BP*1), DI SHRL CX, DI di_finish: SHLL CX, DI BSWAPL SI // reverse order of bytes BSWAPL DI XORL SI, DI // find bit differences JEQ allsame BSRL DI, CX // index of highest bit difference SHRL CX, SI // move a's bit to bottom ANDL $1, SI // mask bit LEAL -1(SI*2), BX // 1/0 => +1/-1 MOVL BX, (AX) RET // all the bytes in common are the same, so we just need // to compare the lengths. allsame: XORL BX, BX XORL CX, CX TESTL DX, DX SETLT BX // 1 if alen > blen SETEQ CX // 1 if alen == blen LEAL -1(CX)(BX*2), BX // 1,0,-1 result MOVL BX, (AX) RET