xref: /linux/arch/alpha/lib/clear_user.S (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1/*
2 * arch/alpha/lib/clear_user.S
3 * Contributed by Richard Henderson <rth@tamu.edu>
4 *
5 * Zero user space, handling exceptions as we go.
6 *
7 * We have to make sure that $0 is always up-to-date and contains the
8 * right "bytes left to zero" value (and that it is updated only _after_
9 * a successful copy).  There is also some rather minor exception setup
10 * stuff.
11 *
12 * NOTE! This is not directly C-callable, because the calling semantics
13 * are different:
14 *
15 * Inputs:
16 *	length in $0
17 *	destination address in $6
18 *	exception pointer in $7
19 *	return address in $28 (exceptions expect it there)
20 *
21 * Outputs:
22 *	bytes left to copy in $0
23 *
24 * Clobbers:
25 *	$1,$2,$3,$4,$5,$6
26 */
27
28/* Allow an exception for an insn; exit if we get one.  */
29#define EX(x,y...)			\
30	99: x,##y;			\
31	.section __ex_table,"a";	\
32	.long 99b - .;			\
33	lda $31, $exception-99b($31); 	\
34	.previous
35
36	.set noat
37	.set noreorder
38	.align 4
39
40	.globl __do_clear_user
41	.ent __do_clear_user
42	.frame	$30, 0, $28
43	.prologue 0
44
45$loop:
46	and	$1, 3, $4	# e0    :
47	beq	$4, 1f		# .. e1 :
48
490:	EX( stq_u $31, 0($6) )	# e0    : zero one word
50	subq	$0, 8, $0	# .. e1 :
51	subq	$4, 1, $4	# e0    :
52	addq	$6, 8, $6	# .. e1 :
53	bne	$4, 0b		# e1    :
54	unop			#       :
55
561:	bic	$1, 3, $1	# e0    :
57	beq	$1, $tail	# .. e1 :
58
592:	EX( stq_u $31, 0($6) )	# e0    : zero four words
60	subq	$0, 8, $0	# .. e1 :
61	EX( stq_u $31, 8($6) )	# e0    :
62	subq	$0, 8, $0	# .. e1 :
63	EX( stq_u $31, 16($6) )	# e0    :
64	subq	$0, 8, $0	# .. e1 :
65	EX( stq_u $31, 24($6) )	# e0    :
66	subq	$0, 8, $0	# .. e1 :
67	subq	$1, 4, $1	# e0    :
68	addq	$6, 32, $6	# .. e1 :
69	bne	$1, 2b		# e1    :
70
71$tail:
72	bne	$2, 1f		# e1    : is there a tail to do?
73	ret	$31, ($28), 1	# .. e1 :
74
751:	EX( ldq_u $5, 0($6) )	# e0    :
76	clr	$0		# .. e1 :
77	nop			# e1    :
78	mskqh	$5, $0, $5	# e0    :
79	EX( stq_u $5, 0($6) )	# e0    :
80	ret	$31, ($28), 1	# .. e1 :
81
82__do_clear_user:
83	and	$6, 7, $4	# e0    : find dest misalignment
84	beq	$0, $zerolength # .. e1 :
85	addq	$0, $4, $1	# e0    : bias counter
86	and	$1, 7, $2	# e1    : number of bytes in tail
87	srl	$1, 3, $1	# e0    :
88	beq	$4, $loop	# .. e1 :
89
90	EX( ldq_u $5, 0($6) )	# e0    : load dst word to mask back in
91	beq	$1, $oneword	# .. e1 : sub-word store?
92
93	mskql	$5, $6, $5	# e0    : take care of misaligned head
94	addq	$6, 8, $6	# .. e1 :
95	EX( stq_u $5, -8($6) )	# e0    :
96	addq	$0, $4, $0	# .. e1 : bytes left -= 8 - misalignment
97	subq	$1, 1, $1	# e0    :
98	subq	$0, 8, $0	# .. e1 :
99	br	$loop		# e1    :
100	unop			#       :
101
102$oneword:
103	mskql	$5, $6, $4	# e0    :
104	mskqh	$5, $2, $5	# e0    :
105	or	$5, $4, $5	# e1    :
106	EX( stq_u $5, 0($6) )	# e0    :
107	clr	$0		# .. e1 :
108
109$zerolength:
110$exception:
111	ret	$31, ($28), 1	# .. e1 :
112
113	.end __do_clear_user
114