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
8TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-28
9	MOVW	a_base+0(FP), R2
10	MOVW	a_len+4(FP), R0
11	MOVW	b_base+12(FP), R3
12	MOVW	b_len+16(FP), R1
13	ADD	$28, R13, R7
14	B	cmpbody<>(SB)
15
16TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20
17	MOVW	a_base+0(FP), R2
18	MOVW	a_len+4(FP), R0
19	MOVW	b_base+8(FP), R3
20	MOVW	b_len+12(FP), R1
21	ADD	$20, R13, R7
22	B	cmpbody<>(SB)
23
24// On entry:
25// R0 is the length of a
26// R1 is the length of b
27// R2 points to the start of a
28// R3 points to the start of b
29// R7 points to return value (-1/0/1 will be written here)
30//
31// On exit:
32// R4, R5, R6 and R8 are clobbered
33TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
34	CMP	R2, R3
35	BEQ	samebytes
36	CMP 	R0, R1
37	MOVW 	R0, R6
38	MOVW.LT	R1, R6		// R6 is min(R0, R1)
39
40	CMP	$0, R6
41	BEQ	samebytes
42	CMP	$4, R6
43	ADD	R2, R6		// R2 is current byte in a, R6 is the end of the range to compare
44	BLT	byte_loop	// length < 4
45	AND	$3, R2, R8
46	CMP	$0, R8
47	BNE	byte_loop	// unaligned a, use byte-wise compare (TODO: try to align a)
48aligned_a:
49	AND	$3, R3, R8
50	CMP	$0, R8
51	BNE	byte_loop	// unaligned b, use byte-wise compare
52	AND	$0xfffffffc, R6, R8
53	// length >= 4
54chunk4_loop:
55	MOVW.P	4(R2), R4
56	MOVW.P	4(R3), R5
57	CMP	R4, R5
58	BNE	cmp
59	CMP	R2, R8
60	BNE	chunk4_loop
61	CMP	R2, R6
62	BEQ	samebytes	// all compared bytes were the same; compare lengths
63byte_loop:
64	MOVBU.P	1(R2), R4
65	MOVBU.P	1(R3), R5
66	CMP	R4, R5
67	BNE	ret
68	CMP	R2, R6
69	BNE	byte_loop
70samebytes:
71	CMP	R0, R1
72	MOVW.LT	$1, R0
73	MOVW.GT	$-1, R0
74	MOVW.EQ	$0, R0
75	MOVW	R0, (R7)
76	RET
77ret:
78	// bytes differed
79	MOVW.LT	$1, R0
80	MOVW.GT	$-1, R0
81	MOVW	R0, (R7)
82	RET
83cmp:
84	SUB	$4, R2, R2
85	SUB	$4, R3, R3
86	B	byte_loop
87