1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
// Copyright 2019 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"
#define CTXT S10
// func memequal(a, b unsafe.Pointer, size uintptr) bool
TEXT runtime·memequal<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-25
#ifndef GOEXPERIMENT_regabiargs
MOV a+0(FP), X10
MOV b+8(FP), X11
MOV size+16(FP), X12
MOV $ret+24(FP), X13
#endif
// X10 = a_base
// X11 = b_base
// X12 = size
JMP memequal<>(SB)
// func memequal_varlen(a, b unsafe.Pointer) bool
TEXT runtime·memequal_varlen<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-17
MOV 8(CTXT), X12 // compiler stores size at offset 8 in the closure
#ifndef GOEXPERIMENT_regabiargs
MOV a+0(FP), X10
MOV b+8(FP), X11
MOV $ret+16(FP), X13
#endif
// X10 = a_base
// X11 = b_base
JMP memequal<>(SB)
// On entry X10 and X11 contain pointers, X12 contains length.
// For non-regabi X13 contains address for return value.
// For regabi return value in X10.
TEXT memequal<>(SB),NOSPLIT|NOFRAME,$0
BEQ X10, X11, eq
MOV $32, X23
BLT X12, X23, loop4_check
// Check alignment - if alignment differs we have to do one byte at a time.
AND $3, X10, X9
AND $3, X11, X19
BNE X9, X19, loop4_check
BEQZ X9, loop32_check
// Check one byte at a time until we reach 8 byte alignment.
SUB X9, X12, X12
align:
ADD $-1, X9
MOVBU 0(X10), X19
MOVBU 0(X11), X20
BNE X19, X20, not_eq
ADD $1, X10
ADD $1, X11
BNEZ X9, align
loop32_check:
MOV $32, X9
BLT X12, X9, loop16_check
loop32:
MOV 0(X10), X19
MOV 0(X11), X20
MOV 8(X10), X21
MOV 8(X11), X22
BNE X19, X20, not_eq
BNE X21, X22, not_eq
MOV 16(X10), X14
MOV 16(X11), X15
MOV 24(X10), X16
MOV 24(X11), X17
BNE X14, X15, not_eq
BNE X16, X17, not_eq
ADD $32, X10
ADD $32, X11
ADD $-32, X12
BGE X12, X9, loop32
BEQZ X12, eq
loop16_check:
MOV $16, X23
BLT X12, X23, loop4_check
loop16:
MOV 0(X10), X19
MOV 0(X11), X20
MOV 8(X10), X21
MOV 8(X11), X22
BNE X19, X20, not_eq
BNE X21, X22, not_eq
ADD $16, X10
ADD $16, X11
ADD $-16, X12
BGE X12, X23, loop16
BEQZ X12, eq
loop4_check:
MOV $4, X23
BLT X12, X23, loop1
loop4:
MOVBU 0(X10), X19
MOVBU 0(X11), X20
MOVBU 1(X10), X21
MOVBU 1(X11), X22
BNE X19, X20, not_eq
BNE X21, X22, not_eq
MOVBU 2(X10), X14
MOVBU 2(X11), X15
MOVBU 3(X10), X16
MOVBU 3(X11), X17
BNE X14, X15, not_eq
BNE X16, X17, not_eq
ADD $4, X10
ADD $4, X11
ADD $-4, X12
BGE X12, X23, loop4
loop1:
BEQZ X12, eq
MOVBU 0(X10), X19
MOVBU 0(X11), X20
BNE X19, X20, not_eq
ADD $1, X10
ADD $1, X11
ADD $-1, X12
JMP loop1
not_eq:
#ifndef GOEXPERIMENT_regabiargs
MOVB ZERO, (X13)
#else
MOVB ZERO, X10
#endif
RET
eq:
#ifndef GOEXPERIMENT_regabiargs
MOV $1, X10
MOVB X10, (X13)
#else
MOV $1, X10
#endif
RET
|