| /* SPDX-License-Identifier: GPL-2.0 */ | 
 | /* | 
 |  * arch/alpha/lib/memmove.S | 
 |  * | 
 |  * Barely optimized memmove routine for Alpha EV5. | 
 |  * | 
 |  * This is hand-massaged output from the original memcpy.c.  We defer to | 
 |  * memcpy whenever possible; the backwards copy loops are not unrolled. | 
 |  */ | 
 | #include <asm/export.h>         | 
 | 	.set noat | 
 | 	.set noreorder | 
 | 	.text | 
 |  | 
 | 	.align 4 | 
 | 	.globl memmove | 
 | 	.ent memmove | 
 | memmove: | 
 | 	ldgp $29, 0($27) | 
 | 	unop | 
 | 	nop | 
 | 	.prologue 1 | 
 |  | 
 | 	addq $16,$18,$4 | 
 | 	addq $17,$18,$5 | 
 | 	cmpule $4,$17,$1		/*  dest + n <= src  */ | 
 | 	cmpule $5,$16,$2		/*  dest >= src + n  */ | 
 |  | 
 | 	bis $1,$2,$1 | 
 | 	mov $16,$0 | 
 | 	xor $16,$17,$2 | 
 | 	bne $1,memcpy			!samegp | 
 |  | 
 | 	and $2,7,$2			/* Test for src/dest co-alignment.  */ | 
 | 	and $16,7,$1 | 
 | 	cmpule $16,$17,$3 | 
 | 	bne $3,$memmove_up		/* dest < src */ | 
 |  | 
 | 	and $4,7,$1 | 
 | 	bne $2,$misaligned_dn | 
 | 	unop | 
 | 	beq $1,$skip_aligned_byte_loop_head_dn | 
 |  | 
 | $aligned_byte_loop_head_dn: | 
 | 	lda $4,-1($4) | 
 | 	lda $5,-1($5) | 
 | 	unop | 
 | 	ble $18,$egress | 
 |  | 
 | 	ldq_u $3,0($5) | 
 | 	ldq_u $2,0($4) | 
 | 	lda $18,-1($18) | 
 | 	extbl $3,$5,$1 | 
 |  | 
 | 	insbl $1,$4,$1 | 
 | 	mskbl $2,$4,$2 | 
 | 	bis $1,$2,$1 | 
 | 	and $4,7,$6 | 
 |  | 
 | 	stq_u $1,0($4) | 
 | 	bne $6,$aligned_byte_loop_head_dn | 
 |  | 
 | $skip_aligned_byte_loop_head_dn: | 
 | 	lda $18,-8($18) | 
 | 	blt $18,$skip_aligned_word_loop_dn | 
 |  | 
 | $aligned_word_loop_dn: | 
 | 	ldq $1,-8($5) | 
 | 	nop | 
 | 	lda $5,-8($5) | 
 | 	lda $18,-8($18) | 
 |  | 
 | 	stq $1,-8($4) | 
 | 	nop | 
 | 	lda $4,-8($4) | 
 | 	bge $18,$aligned_word_loop_dn | 
 |  | 
 | $skip_aligned_word_loop_dn: | 
 | 	lda $18,8($18) | 
 | 	bgt $18,$byte_loop_tail_dn | 
 | 	unop | 
 | 	ret $31,($26),1 | 
 |  | 
 | 	.align 4 | 
 | $misaligned_dn: | 
 | 	nop | 
 | 	fnop | 
 | 	unop | 
 | 	beq $18,$egress | 
 |  | 
 | $byte_loop_tail_dn: | 
 | 	ldq_u $3,-1($5) | 
 | 	ldq_u $2,-1($4) | 
 | 	lda $5,-1($5) | 
 | 	lda $4,-1($4) | 
 |  | 
 | 	lda $18,-1($18) | 
 | 	extbl $3,$5,$1 | 
 | 	insbl $1,$4,$1 | 
 | 	mskbl $2,$4,$2 | 
 |  | 
 | 	bis $1,$2,$1 | 
 | 	stq_u $1,0($4) | 
 | 	bgt $18,$byte_loop_tail_dn | 
 | 	br $egress | 
 |  | 
 | $memmove_up: | 
 | 	mov $16,$4 | 
 | 	mov $17,$5 | 
 | 	bne $2,$misaligned_up | 
 | 	beq $1,$skip_aligned_byte_loop_head_up | 
 |  | 
 | $aligned_byte_loop_head_up: | 
 | 	unop | 
 | 	ble $18,$egress | 
 | 	ldq_u $3,0($5) | 
 | 	ldq_u $2,0($4) | 
 |  | 
 | 	lda $18,-1($18) | 
 | 	extbl $3,$5,$1 | 
 | 	insbl $1,$4,$1 | 
 | 	mskbl $2,$4,$2 | 
 |  | 
 | 	bis $1,$2,$1 | 
 | 	lda $5,1($5) | 
 | 	stq_u $1,0($4) | 
 | 	lda $4,1($4) | 
 |  | 
 | 	and $4,7,$6 | 
 | 	bne $6,$aligned_byte_loop_head_up | 
 |  | 
 | $skip_aligned_byte_loop_head_up: | 
 | 	lda $18,-8($18) | 
 | 	blt $18,$skip_aligned_word_loop_up | 
 |  | 
 | $aligned_word_loop_up: | 
 | 	ldq $1,0($5) | 
 | 	nop | 
 | 	lda $5,8($5) | 
 | 	lda $18,-8($18) | 
 |  | 
 | 	stq $1,0($4) | 
 | 	nop | 
 | 	lda $4,8($4) | 
 | 	bge $18,$aligned_word_loop_up | 
 |  | 
 | $skip_aligned_word_loop_up: | 
 | 	lda $18,8($18) | 
 | 	bgt $18,$byte_loop_tail_up | 
 | 	unop | 
 | 	ret $31,($26),1 | 
 |  | 
 | 	.align 4 | 
 | $misaligned_up: | 
 | 	nop | 
 | 	fnop | 
 | 	unop | 
 | 	beq $18,$egress | 
 |  | 
 | $byte_loop_tail_up: | 
 | 	ldq_u $3,0($5) | 
 | 	ldq_u $2,0($4) | 
 | 	lda $18,-1($18) | 
 | 	extbl $3,$5,$1 | 
 |  | 
 | 	insbl $1,$4,$1 | 
 | 	mskbl $2,$4,$2 | 
 | 	bis $1,$2,$1 | 
 | 	stq_u $1,0($4) | 
 |  | 
 | 	lda $5,1($5) | 
 | 	lda $4,1($4) | 
 | 	nop | 
 | 	bgt $18,$byte_loop_tail_up | 
 |  | 
 | $egress: | 
 | 	ret $31,($26),1 | 
 | 	nop | 
 | 	nop | 
 | 	nop | 
 |  | 
 | 	.end memmove | 
 | 	EXPORT_SYMBOL(memmove) |