// 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-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(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