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// memequal(a, b unsafe.Pointer, size uintptr) bool
9TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-13
10	MOVW	a+0(FP), R0
11	MOVW	b+4(FP), R2
12	CMP	R0, R2
13	B.EQ	eq
14	MOVW	size+8(FP), R1
15	CMP	$0, R1
16	B.EQ	eq		// short path to handle 0-byte case
17	MOVW	$ret+12(FP), R7
18	B	memeqbody<>(SB)
19eq:
20	MOVW	$1, R0
21	MOVB	R0, ret+12(FP)
22	RET
23
24// memequal_varlen(a, b unsafe.Pointer) bool
25TEXT runtime·memequal_varlen(SB),NOSPLIT|NOFRAME,$0-9
26	MOVW	a+0(FP), R0
27	MOVW	b+4(FP), R2
28	CMP	R0, R2
29	B.EQ	eq
30	MOVW	4(R7), R1	// compiler stores size at offset 4 in the closure
31	CMP	$0, R1
32	B.EQ	eq		// short path to handle 0-byte case
33	MOVW	$ret+8(FP), R7
34	B	memeqbody<>(SB)
35eq:
36	MOVW	$1, R0
37	MOVB	R0, ret+8(FP)
38	RET
39
40// Input:
41// R0: data of a
42// R1: length
43// R2: data of b
44// R7: points to return value
45//
46// On exit:
47// R4, R5 and R6 are clobbered
48TEXT memeqbody<>(SB),NOSPLIT|NOFRAME,$0-0
49	CMP	$1, R1
50	B.EQ	one		// 1-byte special case for better performance
51
52	CMP	$4, R1
53	ADD	R0, R1		// R1 is the end of the range to compare
54	B.LT	byte_loop	// length < 4
55	AND	$3, R0, R6
56	CMP	$0, R6
57	B.NE	byte_loop	// unaligned a, use byte-wise compare (TODO: try to align a)
58	AND	$3, R2, R6
59	CMP	$0, R6
60	B.NE	byte_loop	// unaligned b, use byte-wise compare
61	AND	$0xfffffffc, R1, R6
62	// length >= 4
63chunk4_loop:
64	MOVW.P	4(R0), R4
65	MOVW.P	4(R2), R5
66	CMP	R4, R5
67	B.NE	notequal
68	CMP	R0, R6
69	B.NE	chunk4_loop
70	CMP	R0, R1
71	B.EQ	equal		// reached the end
72byte_loop:
73	MOVBU.P	1(R0), R4
74	MOVBU.P	1(R2), R5
75	CMP	R4, R5
76	B.NE	notequal
77	CMP	R0, R1
78	B.NE	byte_loop
79equal:
80	MOVW	$1, R0
81	MOVB	R0, (R7)
82	RET
83one:
84	MOVBU	(R0), R4
85	MOVBU	(R2), R5
86	CMP	R4, R5
87	B.EQ	equal
88notequal:
89	MOVW	$0, R0
90	MOVB	R0, (R7)
91	RET
92