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