Skip to content
Snippets Groups Projects
compare_arm.s 1.75 KiB
Newer Older
  • Learn to ignore specific revisions
  • // 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-28
    	MOVW	a_base+0(FP), R2
    	MOVW	a_len+4(FP), R0
    	MOVW	b_base+12(FP), R3
    	MOVW	b_len+16(FP), R1
    	ADD	$28, R13, R7
    	B	cmpbody<>(SB)
    
    TEXT runtime·cmpstring(SB),NOSPLIT|NOFRAME,$0-20
    	MOVW	a_base+0(FP), R2
    	MOVW	a_len+4(FP), R0
    	MOVW	b_base+8(FP), R3
    	MOVW	b_len+12(FP), R1
    	ADD	$20, R13, 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 and R8 are clobbered
    
    TEXT cmpbody<>(SB),NOSPLIT|NOFRAME,$0-0
    	CMP	R2, R3
    	BEQ	samebytes
    	CMP 	R0, R1
    	MOVW 	R0, R6
    
    	MOVW.LT	R1, R6		// R6 is min(R0, R1)
    
    	CMP	$0, R6
    	BEQ	samebytes
    	CMP	$4, R6
    	ADD	R2, R6		// R2 is current byte in a, R6 is the end of the range to compare
    	BLT	byte_loop	// length < 4
    	AND	$3, R2, R8
    	CMP	$0, R8
    	BNE	byte_loop	// unaligned a, use byte-wise compare (TODO: try to align a)
    aligned_a:
    	AND	$3, R3, R8
    	CMP	$0, R8
    	BNE	byte_loop	// unaligned b, use byte-wise compare
    	AND	$0xfffffffc, R6, R8
    	// length >= 4
    chunk4_loop:
    	MOVW.P	4(R2), R4
    	MOVW.P	4(R3), R5
    	CMP	R4, R5
    	BNE	cmp
    	CMP	R2, R8
    	BNE	chunk4_loop
    
    	BEQ	samebytes	// all compared bytes were the same; compare lengths
    byte_loop:
    
    	MOVBU.P	1(R2), R4
    	MOVBU.P	1(R3), R5
    	CMP	R4, R5
    
    	BNE	ret
    	CMP	R2, R6
    	BNE	byte_loop
    samebytes:
    	CMP	R0, R1
    
    	MOVW.LT	$1, R0
    	MOVW.GT	$-1, R0
    
    	MOVW.LT	$1, R0
    	MOVW.GT	$-1, R0
    	MOVW	R0, (R7)
    	RET
    
    cmp:
    	SUB	$4, R2, R2
    	SUB	$4, R3, R3
    	B	byte_loop