aboutsummaryrefslogtreecommitdiff
path: root/src/internal/bytealg/equal_riscv64.s
blob: 77202d60759208073da39f9eb804968982f67e82 (plain)
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