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