| // 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 | |
| MOVD a_base+0(FP), R2 | |
| MOVD a_len+8(FP), R0 | |
| MOVD b_base+24(FP), R3 | |
| MOVD b_len+32(FP), R1 | |
| MOVD $ret+48(FP), R7 | |
| B cmpbody<>(SB) | |
| TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-40 | |
| MOVD a_base+0(FP), R2 | |
| MOVD a_len+8(FP), R0 | |
| MOVD b_base+16(FP), R3 | |
| MOVD b_len+24(FP), R1 | |
| MOVD $ret+32(FP), 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, R8, R9 and R10 are clobbered | |
| TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0 | |
| CMP R2, R3 | |
| BEQ samebytes // same starting pointers; compare lengths | |
| CMP R0, R1 | |
| CSEL LT, R1, R0, R6 // R6 is min(R0, R1) | |
| CBZ R6, samebytes | |
| BIC $0xf, R6, R10 | |
| CBZ R10, small // length < 16 | |
| ADD R2, R10 // end of chunk16 | |
| // length >= 16 | |
| chunk16_loop: | |
| LDP.P 16(R2), (R4, R8) | |
| LDP.P 16(R3), (R5, R9) | |
| CMP R4, R5 | |
| BNE cmp | |
| CMP R8, R9 | |
| BNE cmpnext | |
| CMP R10, R2 | |
| BNE chunk16_loop | |
| AND $0xf, R6, R6 | |
| CBZ R6, samebytes | |
| SUBS $8, R6 | |
| BLT tail | |
| // the length of tail > 8 bytes | |
| MOVD.P 8(R2), R4 | |
| MOVD.P 8(R3), R5 | |
| CMP R4, R5 | |
| BNE cmp | |
| SUB $8, R6 | |
| // compare last 8 bytes | |
| tail: | |
| MOVD (R2)(R6), R4 | |
| MOVD (R3)(R6), R5 | |
| CMP R4, R5 | |
| BEQ samebytes | |
| cmp: | |
| REV R4, R4 | |
| REV R5, R5 | |
| CMP R4, R5 | |
| ret: | |
| MOVD $1, R4 | |
| CNEG HI, R4, R4 | |
| MOVD R4, (R7) | |
| RET | |
| small: | |
| TBZ $3, R6, lt_8 | |
| MOVD (R2), R4 | |
| MOVD (R3), R5 | |
| CMP R4, R5 | |
| BNE cmp | |
| SUBS $8, R6 | |
| BEQ samebytes | |
| ADD $8, R2 | |
| ADD $8, R3 | |
| SUB $8, R6 | |
| B tail | |
| lt_8: | |
| TBZ $2, R6, lt_4 | |
| MOVWU (R2), R4 | |
| MOVWU (R3), R5 | |
| CMPW R4, R5 | |
| BNE cmp | |
| SUBS $4, R6 | |
| BEQ samebytes | |
| ADD $4, R2 | |
| ADD $4, R3 | |
| lt_4: | |
| TBZ $1, R6, lt_2 | |
| MOVHU (R2), R4 | |
| MOVHU (R3), R5 | |
| CMPW R4, R5 | |
| BNE cmp | |
| ADD $2, R2 | |
| ADD $2, R3 | |
| lt_2: | |
| TBZ $0, R6, samebytes | |
| one: | |
| MOVBU (R2), R4 | |
| MOVBU (R3), R5 | |
| CMPW R4, R5 | |
| BNE ret | |
| samebytes: | |
| CMP R1, R0 | |
| CSET NE, R4 | |
| CNEG LO, R4, R4 | |
| MOVD R4, (R7) | |
| RET | |
| cmpnext: | |
| REV R8, R4 | |
| REV R9, R5 | |
| CMP R4, R5 | |
| B ret |