github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/internal/bytealg/equal_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 ·Equal(SB),NOSPLIT,$0-49 9 MOVD a_len+8(FP), R1 10 MOVD b_len+32(FP), R3 11 CMP R1, R3 12 // unequal lengths are not equal 13 BNE not_equal 14 // short path to handle 0-byte case 15 CBZ R1, equal 16 MOVD a_base+0(FP), R0 17 MOVD b_base+24(FP), R2 18 MOVD $ret+48(FP), R8 19 B memeqbody<>(SB) 20 equal: 21 MOVD $1, R0 22 MOVB R0, ret+48(FP) 23 RET 24 not_equal: 25 MOVB ZR, ret+48(FP) 26 RET 27 28 TEXT bytes·Equal(SB),NOSPLIT,$0-49 29 FUNCDATA $0, ·Equal·args_stackmap(SB) 30 MOVD a_len+8(FP), R1 31 MOVD b_len+32(FP), R3 32 CMP R1, R3 33 // unequal lengths are not equal 34 BNE not_equal 35 // short path to handle 0-byte case 36 CBZ R1, equal 37 MOVD a_base+0(FP), R0 38 MOVD b_base+24(FP), R2 39 MOVD $ret+48(FP), R8 40 B memeqbody<>(SB) 41 equal: 42 MOVD $1, R0 43 MOVB R0, ret+48(FP) 44 RET 45 not_equal: 46 MOVB ZR, ret+48(FP) 47 RET 48 49 // memequal(a, b unsafe.Pointer, size uintptr) bool 50 TEXT runtime·memequal(SB),NOSPLIT|NOFRAME,$0-25 51 MOVD size+16(FP), R1 52 // short path to handle 0-byte case 53 CBZ R1, equal 54 MOVD a+0(FP), R0 55 MOVD b+8(FP), R2 56 MOVD $ret+24(FP), R8 57 B memeqbody<>(SB) 58 equal: 59 MOVD $1, R0 60 MOVB R0, ret+24(FP) 61 RET 62 63 // memequal_varlen(a, b unsafe.Pointer) bool 64 TEXT runtime·memequal_varlen(SB),NOSPLIT,$40-17 65 MOVD a+0(FP), R3 66 MOVD b+8(FP), R4 67 CMP R3, R4 68 BEQ eq 69 MOVD 8(R26), R5 // compiler stores size at offset 8 in the closure 70 CBZ R5, eq 71 MOVD R3, 8(RSP) 72 MOVD R4, 16(RSP) 73 MOVD R5, 24(RSP) 74 BL runtime·memequal(SB) 75 MOVBU 32(RSP), R3 76 MOVB R3, ret+16(FP) 77 RET 78 eq: 79 MOVD $1, R3 80 MOVB R3, ret+16(FP) 81 RET 82 83 // input: 84 // R0: pointer a 85 // R1: data len 86 // R2: pointer b 87 // R8: address to put result 88 TEXT memeqbody<>(SB),NOSPLIT,$0 89 CMP $1, R1 90 // handle 1-byte special case for better performance 91 BEQ one 92 CMP $16, R1 93 // handle specially if length < 16 94 BLO tail 95 BIC $0x3f, R1, R3 96 CBZ R3, chunk16 97 // work with 64-byte chunks 98 ADD R3, R0, R6 // end of chunks 99 chunk64_loop: 100 VLD1.P (R0), [V0.D2, V1.D2, V2.D2, V3.D2] 101 VLD1.P (R2), [V4.D2, V5.D2, V6.D2, V7.D2] 102 VCMEQ V0.D2, V4.D2, V8.D2 103 VCMEQ V1.D2, V5.D2, V9.D2 104 VCMEQ V2.D2, V6.D2, V10.D2 105 VCMEQ V3.D2, V7.D2, V11.D2 106 VAND V8.B16, V9.B16, V8.B16 107 VAND V8.B16, V10.B16, V8.B16 108 VAND V8.B16, V11.B16, V8.B16 109 CMP R0, R6 110 VMOV V8.D[0], R4 111 VMOV V8.D[1], R5 112 CBZ R4, not_equal 113 CBZ R5, not_equal 114 BNE chunk64_loop 115 AND $0x3f, R1, R1 116 CBZ R1, equal 117 chunk16: 118 // work with 16-byte chunks 119 BIC $0xf, R1, R3 120 CBZ R3, tail 121 ADD R3, R0, R6 // end of chunks 122 chunk16_loop: 123 LDP.P 16(R0), (R4, R5) 124 LDP.P 16(R2), (R7, R9) 125 EOR R4, R7 126 CBNZ R7, not_equal 127 EOR R5, R9 128 CBNZ R9, not_equal 129 CMP R0, R6 130 BNE chunk16_loop 131 AND $0xf, R1, R1 132 CBZ R1, equal 133 tail: 134 // special compare of tail with length < 16 135 TBZ $3, R1, lt_8 136 MOVD (R0), R4 137 MOVD (R2), R5 138 EOR R4, R5 139 CBNZ R5, not_equal 140 SUB $8, R1, R6 // offset of the last 8 bytes 141 MOVD (R0)(R6), R4 142 MOVD (R2)(R6), R5 143 EOR R4, R5 144 CBNZ R5, not_equal 145 B equal 146 lt_8: 147 TBZ $2, R1, lt_4 148 MOVWU (R0), R4 149 MOVWU (R2), R5 150 EOR R4, R5 151 CBNZ R5, not_equal 152 SUB $4, R1, R6 // offset of the last 4 bytes 153 MOVWU (R0)(R6), R4 154 MOVWU (R2)(R6), R5 155 EOR R4, R5 156 CBNZ R5, not_equal 157 B equal 158 lt_4: 159 TBZ $1, R1, lt_2 160 MOVHU.P 2(R0), R4 161 MOVHU.P 2(R2), R5 162 CMP R4, R5 163 BNE not_equal 164 lt_2: 165 TBZ $0, R1, equal 166 one: 167 MOVBU (R0), R4 168 MOVBU (R2), R5 169 CMP R4, R5 170 BNE not_equal 171 equal: 172 MOVD $1, R0 173 MOVB R0, (R8) 174 RET 175 not_equal: 176 MOVB ZR, (R8) 177 RET