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
145
View as plain text