github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/internal/bytealg/compare_arm64.s (about) 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 8 TEXT ·Compare<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-56 9 #ifdef GOEXPERIMENT_regabiargs 10 // R0 = a_base (want in R0) 11 // R1 = a_len (want in R1) 12 // R2 = a_cap (unused) 13 // R3 = b_base (want in R2) 14 // R4 = b_len (want in R3) 15 // R5 = b_cap (unused) 16 MOVD R3, R2 17 MOVD R4, R3 18 #else 19 MOVD a_base+0(FP), R0 20 MOVD a_len+8(FP), R1 21 MOVD b_base+24(FP), R2 22 MOVD b_len+32(FP), R3 23 MOVD $ret+48(FP), R7 24 #endif 25 B cmpbody<>(SB) 26 27 TEXT runtime·cmpstring<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-40 28 #ifdef GOEXPERIMENT_regabiargs 29 // R0 = a_base 30 // R1 = a_len 31 // R2 = b_base 32 // R3 = b_len 33 #else 34 MOVD a_base+0(FP), R0 35 MOVD a_len+8(FP), R1 36 MOVD b_base+16(FP), R2 37 MOVD b_len+24(FP), R3 38 MOVD $ret+32(FP), R7 39 #endif 40 B cmpbody<>(SB) 41 42 // On entry: 43 // R0 points to the start of a 44 // R1 is the length of a 45 // R2 points to the start of b 46 // R3 is the length of b 47 #ifndef GOEXPERIMENT_regabiargs 48 // R7 points to return value (-1/0/1 will be written here) 49 #endif 50 // 51 // On exit: 52 #ifdef GOEXPERIMENT_regabiargs 53 // R0 is the result 54 #endif 55 // R4, R5, R6, R8, R9 and R10 are clobbered 56 TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0 57 CMP R0, R2 58 BEQ samebytes // same starting pointers; compare lengths 59 CMP R1, R3 60 CSEL LT, R3, R1, R6 // R6 is min(R1, R3) 61 62 CBZ R6, samebytes 63 BIC $0xf, R6, R10 64 CBZ R10, small // length < 16 65 ADD R0, R10 // end of chunk16 66 // length >= 16 67 chunk16_loop: 68 LDP.P 16(R0), (R4, R8) 69 LDP.P 16(R2), (R5, R9) 70 CMP R4, R5 71 BNE cmp 72 CMP R8, R9 73 BNE cmpnext 74 CMP R10, R0 75 BNE chunk16_loop 76 AND $0xf, R6, R6 77 CBZ R6, samebytes 78 SUBS $8, R6 79 BLT tail 80 // the length of tail > 8 bytes 81 MOVD.P 8(R0), R4 82 MOVD.P 8(R2), R5 83 CMP R4, R5 84 BNE cmp 85 SUB $8, R6 86 // compare last 8 bytes 87 tail: 88 MOVD (R0)(R6), R4 89 MOVD (R2)(R6), R5 90 CMP R4, R5 91 BEQ samebytes 92 cmp: 93 REV R4, R4 94 REV R5, R5 95 CMP R4, R5 96 ret: 97 MOVD $1, R0 98 CNEG HI, R0, R0 99 #ifndef GOEXPERIMENT_regabiargs 100 MOVD R0, (R7) 101 #endif 102 RET 103 small: 104 TBZ $3, R6, lt_8 105 MOVD (R0), R4 106 MOVD (R2), R5 107 CMP R4, R5 108 BNE cmp 109 SUBS $8, R6 110 BEQ samebytes 111 ADD $8, R0 112 ADD $8, R2 113 SUB $8, R6 114 B tail 115 lt_8: 116 TBZ $2, R6, lt_4 117 MOVWU (R0), R4 118 MOVWU (R2), R5 119 CMPW R4, R5 120 BNE cmp 121 SUBS $4, R6 122 BEQ samebytes 123 ADD $4, R0 124 ADD $4, R2 125 lt_4: 126 TBZ $1, R6, lt_2 127 MOVHU (R0), R4 128 MOVHU (R2), R5 129 CMPW R4, R5 130 BNE cmp 131 ADD $2, R0 132 ADD $2, R2 133 lt_2: 134 TBZ $0, R6, samebytes 135 one: 136 MOVBU (R0), R4 137 MOVBU (R2), R5 138 CMPW R4, R5 139 BNE ret 140 samebytes: 141 CMP R3, R1 142 CSET NE, R0 143 CNEG LO, R0, R0 144 #ifndef GOEXPERIMENT_regabiargs 145 MOVD R0, (R7) 146 #endif 147 RET 148 cmpnext: 149 REV R8, R4 150 REV R9, R5 151 CMP R4, R5 152 B ret