| | // 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 |
| |
|