xref: /OK3568_Linux_fs/kernel/arch/alpha/lib/strncpy.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun * arch/alpha/lib/strncpy.S
4*4882a593Smuzhiyun * Contributed by Richard Henderson (rth@tamu.edu)
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copy no more than COUNT bytes of the null-terminated string from
7*4882a593Smuzhiyun * SRC to DST.  If SRC does not cover all of COUNT, the balance is
8*4882a593Smuzhiyun * zeroed.
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Or, rather, if the kernel cared about that weird ANSI quirk.  This
11*4882a593Smuzhiyun * version has cropped that bit o' nastiness as well as assuming that
12*4882a593Smuzhiyun * __stxncpy is in range of a branch.
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun#include <asm/export.h>
15*4882a593Smuzhiyun	.set noat
16*4882a593Smuzhiyun	.set noreorder
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun	.text
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun	.align 4
21*4882a593Smuzhiyun	.globl strncpy
22*4882a593Smuzhiyun	.ent strncpy
23*4882a593Smuzhiyunstrncpy:
24*4882a593Smuzhiyun	.frame $30, 0, $26
25*4882a593Smuzhiyun	.prologue 0
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun	mov	$16, $0		# set return value now
28*4882a593Smuzhiyun	beq	$18, $zerolen
29*4882a593Smuzhiyun	unop
30*4882a593Smuzhiyun	bsr	$23, __stxncpy	# do the work of the copy
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun	unop
33*4882a593Smuzhiyun	bne	$18, $multiword	# do we have full words left?
34*4882a593Smuzhiyun	subq	$24, 1, $3	# nope
35*4882a593Smuzhiyun	subq	$27, 1, $4
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun	or	$3, $24, $3	# clear the bits between the last
38*4882a593Smuzhiyun	or	$4, $27, $4	# written byte and the last byte in COUNT
39*4882a593Smuzhiyun	andnot	$3, $4, $4
40*4882a593Smuzhiyun	zap	$1, $4, $1
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun	stq_u	$1, 0($16)
43*4882a593Smuzhiyun	ret
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun	.align	4
46*4882a593Smuzhiyun$multiword:
47*4882a593Smuzhiyun	subq	$27, 1, $2	# clear the final bits in the prev word
48*4882a593Smuzhiyun	or	$2, $27, $2
49*4882a593Smuzhiyun	zapnot	$1, $2, $1
50*4882a593Smuzhiyun	subq	$18, 1, $18
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun	stq_u	$1, 0($16)
53*4882a593Smuzhiyun	addq	$16, 8, $16
54*4882a593Smuzhiyun	unop
55*4882a593Smuzhiyun	beq	$18, 1f
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun	nop
58*4882a593Smuzhiyun	unop
59*4882a593Smuzhiyun	nop
60*4882a593Smuzhiyun	blbc	$18, 0f
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun	stq_u	$31, 0($16)	# zero one word
63*4882a593Smuzhiyun	subq	$18, 1, $18
64*4882a593Smuzhiyun	addq	$16, 8, $16
65*4882a593Smuzhiyun	beq	$18, 1f
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun0:	stq_u	$31, 0($16)	# zero two words
68*4882a593Smuzhiyun	subq	$18, 2, $18
69*4882a593Smuzhiyun	stq_u	$31, 8($16)
70*4882a593Smuzhiyun	addq	$16, 16, $16
71*4882a593Smuzhiyun	bne	$18, 0b
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun1:	ldq_u	$1, 0($16)	# clear the leading bits in the final word
74*4882a593Smuzhiyun	subq	$24, 1, $2
75*4882a593Smuzhiyun	or	$2, $24, $2
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun	zap	$1, $2, $1
78*4882a593Smuzhiyun	stq_u	$1, 0($16)
79*4882a593Smuzhiyun$zerolen:
80*4882a593Smuzhiyun	ret
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun	.end	strncpy
83*4882a593Smuzhiyun	EXPORT_SYMBOL(strncpy)
84