mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-06 13:37:36 +03:00
This CL ports a few performance-critical assembly functions to use register arguments directly. This is similar to CL 308931 and CL 310184. Change-Id: I6e30dfff17f76b8578ce8cfd51de21b66610fdb0 Reviewed-on: https://go-review.googlesource.com/c/go/+/324400 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org>
152 lines
2.7 KiB
ArmAsm
152 lines
2.7 KiB
ArmAsm
// 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
|