// Copyright 2018 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"
TEXT ·Compare(SB),NOSPLIT|NOFRAME,$0-28
MOVW a_base+0(FP), R2
MOVW a_len+4(FP), R0
MOVW b_base+12(FP), R3
MOVW b_len+16(FP), R1
ADD $28, R13, R7
B cmpbody<>(SB)
TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20
MOVW a_base+0(FP), R2
MOVW a_len+4(FP), R0
MOVW b_base+8(FP), R3
MOVW b_len+12(FP), R1
ADD $20, R13, R7
B cmpbody<>(SB)
// On entry:
// R0 is the length of a
// R1 is the length of b
// R2 points to the start of a
// R3 points to the start of b
// R7 points to return value (-1/0/1 will be written here)
//
// On exit:
// R4, R5, R6 and R8 are clobbered
TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
CMP R2, R3
BEQ samebytes
CMP R0, R1
MOVW R0, R6
MOVW.LT R1, R6 // R6 is min(R0, R1)
CMP $0, R6
BEQ samebytes
CMP $4, R6
ADD R2, R6 // R2 is current byte in a, R6 is the end of the range to compare
BLT byte_loop // length < 4
AND $3, R2, R8
CMP $0, R8
BNE byte_loop // unaligned a, use byte-wise compare (TODO: try to align a)
aligned_a:
AND $3, R3, R8
CMP $0, R8
BNE byte_loop // unaligned b, use byte-wise compare
AND $0xfffffffc, R6, R8
// length >= 4
chunk4_loop:
MOVW.P 4(R2), R4
MOVW.P 4(R3), R5
CMP R4, R5
BNE cmp
CMP R2, R8
BNE chunk4_loop
CMP R2, R6
BEQ samebytes // all compared bytes were the same; compare lengths
byte_loop:
MOVBU.P 1(R2), R4
MOVBU.P 1(R3), R5
CMP R4, R5
BNE ret
CMP R2, R6
BNE byte_loop
samebytes:
CMP R0, R1
MOVW.LT $1, R0
MOVW.GT $-1, R0
MOVW.EQ $0, R0
MOVW R0, (R7)
RET
ret:
// bytes differed
MOVW.LT $1, R0
MOVW.GT $-1, R0
MOVW R0, (R7)
RET
cmp:
SUB $4, R2, R2
SUB $4, R3, R3
B byte_loop
|