xref: /OK3568_Linux_fs/kernel/arch/alpha/lib/clear_user.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0 */
2*4882a593Smuzhiyun/*
3*4882a593Smuzhiyun * arch/alpha/lib/clear_user.S
4*4882a593Smuzhiyun * Contributed by Richard Henderson <rth@tamu.edu>
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Zero user space, handling exceptions as we go.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * We have to make sure that $0 is always up-to-date and contains the
9*4882a593Smuzhiyun * right "bytes left to zero" value (and that it is updated only _after_
10*4882a593Smuzhiyun * a successful copy).  There is also some rather minor exception setup
11*4882a593Smuzhiyun * stuff.
12*4882a593Smuzhiyun */
13*4882a593Smuzhiyun#include <asm/export.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun/* Allow an exception for an insn; exit if we get one.  */
16*4882a593Smuzhiyun#define EX(x,y...)			\
17*4882a593Smuzhiyun	99: x,##y;			\
18*4882a593Smuzhiyun	.section __ex_table,"a";	\
19*4882a593Smuzhiyun	.long 99b - .;			\
20*4882a593Smuzhiyun	lda $31, $exception-99b($31); 	\
21*4882a593Smuzhiyun	.previous
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun	.set noat
24*4882a593Smuzhiyun	.set noreorder
25*4882a593Smuzhiyun	.align 4
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun	.globl __clear_user
28*4882a593Smuzhiyun	.ent __clear_user
29*4882a593Smuzhiyun	.frame	$30, 0, $26
30*4882a593Smuzhiyun	.prologue 0
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun$loop:
33*4882a593Smuzhiyun	and	$1, 3, $4	# e0    :
34*4882a593Smuzhiyun	beq	$4, 1f		# .. e1 :
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun0:	EX( stq_u $31, 0($16) )	# e0    : zero one word
37*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
38*4882a593Smuzhiyun	subq	$4, 1, $4	# e0    :
39*4882a593Smuzhiyun	addq	$16, 8, $16	# .. e1 :
40*4882a593Smuzhiyun	bne	$4, 0b		# e1    :
41*4882a593Smuzhiyun	unop			#       :
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun1:	bic	$1, 3, $1	# e0    :
44*4882a593Smuzhiyun	beq	$1, $tail	# .. e1 :
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun2:	EX( stq_u $31, 0($16) )	# e0    : zero four words
47*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
48*4882a593Smuzhiyun	EX( stq_u $31, 8($16) )	# e0    :
49*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
50*4882a593Smuzhiyun	EX( stq_u $31, 16($16) )	# e0    :
51*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
52*4882a593Smuzhiyun	EX( stq_u $31, 24($16) )	# e0    :
53*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
54*4882a593Smuzhiyun	subq	$1, 4, $1	# e0    :
55*4882a593Smuzhiyun	addq	$16, 32, $16	# .. e1 :
56*4882a593Smuzhiyun	bne	$1, 2b		# e1    :
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun$tail:
59*4882a593Smuzhiyun	bne	$2, 1f		# e1    : is there a tail to do?
60*4882a593Smuzhiyun	ret	$31, ($26), 1	# .. e1 :
61*4882a593Smuzhiyun
62*4882a593Smuzhiyun1:	EX( ldq_u $5, 0($16) )	# e0    :
63*4882a593Smuzhiyun	clr	$0		# .. e1 :
64*4882a593Smuzhiyun	nop			# e1    :
65*4882a593Smuzhiyun	mskqh	$5, $0, $5	# e0    :
66*4882a593Smuzhiyun	EX( stq_u $5, 0($16) )	# e0    :
67*4882a593Smuzhiyun	ret	$31, ($26), 1	# .. e1 :
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun__clear_user:
70*4882a593Smuzhiyun	and	$17, $17, $0
71*4882a593Smuzhiyun	and	$16, 7, $4	# e0    : find dest misalignment
72*4882a593Smuzhiyun	beq	$0, $zerolength # .. e1 :
73*4882a593Smuzhiyun	addq	$0, $4, $1	# e0    : bias counter
74*4882a593Smuzhiyun	and	$1, 7, $2	# e1    : number of bytes in tail
75*4882a593Smuzhiyun	srl	$1, 3, $1	# e0    :
76*4882a593Smuzhiyun	beq	$4, $loop	# .. e1 :
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun	EX( ldq_u $5, 0($16) )	# e0    : load dst word to mask back in
79*4882a593Smuzhiyun	beq	$1, $oneword	# .. e1 : sub-word store?
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun	mskql	$5, $16, $5	# e0    : take care of misaligned head
82*4882a593Smuzhiyun	addq	$16, 8, $16	# .. e1 :
83*4882a593Smuzhiyun	EX( stq_u $5, -8($16) )	# e0    :
84*4882a593Smuzhiyun	addq	$0, $4, $0	# .. e1 : bytes left -= 8 - misalignment
85*4882a593Smuzhiyun	subq	$1, 1, $1	# e0    :
86*4882a593Smuzhiyun	subq	$0, 8, $0	# .. e1 :
87*4882a593Smuzhiyun	br	$loop		# e1    :
88*4882a593Smuzhiyun	unop			#       :
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun$oneword:
91*4882a593Smuzhiyun	mskql	$5, $16, $4	# e0    :
92*4882a593Smuzhiyun	mskqh	$5, $2, $5	# e0    :
93*4882a593Smuzhiyun	or	$5, $4, $5	# e1    :
94*4882a593Smuzhiyun	EX( stq_u $5, 0($16) )	# e0    :
95*4882a593Smuzhiyun	clr	$0		# .. e1 :
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun$zerolength:
98*4882a593Smuzhiyun$exception:
99*4882a593Smuzhiyun	ret	$31, ($26), 1	# .. e1 :
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun	.end __clear_user
102*4882a593Smuzhiyun	EXPORT_SYMBOL(__clear_user)
103