blob: 5a80207258313dbb984be319d5818aa74498fcea [file] [log] [blame]
// 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<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56
#ifdef GOEXPERIMENT_regabiargs
// R0 = a_base (want in R0)
// R1 = a_len (want in R1)
// R2 = a_cap (unused)
// R3 = b_base (want in R2)
// R4 = b_len (want in R3)
// R5 = b_cap (unused)
MOVD R3, R2
MOVD R4, R3
#else
MOVD a_base+0(FP), R0
MOVD a_len+8(FP), R1
MOVD b_base+24(FP), R2
MOVD b_len+32(FP), R3
MOVD $ret+48(FP), R7
#endif
B cmpbody<>(SB)
TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40
#ifdef GOEXPERIMENT_regabiargs
// R0 = a_base
// R1 = a_len
// R2 = b_base
// R3 = b_len
#else
MOVD a_base+0(FP), R0
MOVD a_len+8(FP), R1
MOVD b_base+16(FP), R2
MOVD b_len+24(FP), R3
MOVD $ret+32(FP), R7
#endif
B cmpbody<>(SB)
// On entry:
// R0 points to the start of a
// R1 is the length of a
// R2 points to the start of b
// R3 is the length of b
#ifndef GOEXPERIMENT_regabiargs
// R7 points to return value (-1/0/1 will be written here)
#endif
//
// On exit:
#ifdef GOEXPERIMENT_regabiargs
// R0 is the result
#endif
// R4, R5, R6, R8, R9 and R10 are clobbered
TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
CMP R0, R2
BEQ samebytes // same starting pointers; compare lengths
CMP R1, R3
CSEL LT, R3, R1, R6 // R6 is min(R1, R3)
CBZ R6, samebytes
BIC $0xf, R6, R10
CBZ R10, small // length < 16
ADD R0, R10 // end of chunk16
// length >= 16
chunk16_loop:
LDP.P 16(R0), (R4, R8)
LDP.P 16(R2), (R5, R9)
CMP R4, R5
BNE cmp
CMP R8, R9
BNE cmpnext
CMP R10, R0
BNE chunk16_loop
AND $0xf, R6, R6
CBZ R6, samebytes
SUBS $8, R6
BLT tail
// the length of tail > 8 bytes
MOVD.P 8(R0), R4
MOVD.P 8(R2), R5
CMP R4, R5
BNE cmp
SUB $8, R6
// compare last 8 bytes
tail:
MOVD (R0)(R6), R4
MOVD (R2)(R6), R5
CMP R4, R5
BEQ samebytes
cmp:
REV R4, R4
REV R5, R5
CMP R4, R5
ret:
MOVD $1, R0
CNEG HI, R0, R0
#ifndef GOEXPERIMENT_regabiargs
MOVD R0, (R7)
#endif
RET
small:
TBZ $3, R6, lt_8
MOVD (R0), R4
MOVD (R2), R5
CMP R4, R5
BNE cmp
SUBS $8, R6
BEQ samebytes
ADD $8, R0
ADD $8, R2
SUB $8, R6
B tail
lt_8:
TBZ $2, R6, lt_4
MOVWU (R0), R4
MOVWU (R2), R5
CMPW R4, R5
BNE cmp
SUBS $4, R6
BEQ samebytes
ADD $4, R0
ADD $4, R2
lt_4:
TBZ $1, R6, lt_2
MOVHU (R0), R4
MOVHU (R2), R5
CMPW R4, R5
BNE cmp
ADD $2, R0
ADD $2, R2
lt_2:
TBZ $0, R6, samebytes
one:
MOVBU (R0), R4
MOVBU (R2), R5
CMPW R4, R5
BNE ret
samebytes:
CMP R3, R1
CSET NE, R0
CNEG LO, R0, R0
#ifndef GOEXPERIMENT_regabiargs
MOVD R0, (R7)
#endif
RET
cmpnext:
REV R8, R4
REV R9, R5
CMP R4, R5
B ret