xref: /linux/arch/alpha/lib/clear_user.S (revision ab520be8cd5d56867fc95cfbc34b90880faf1f9d)
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#include <asm/export.h>
28
29/* Allow an exception for an insn; exit if we get one.  */
30#define EX(x,y...)			\
31	99: x,##y;			\
32	.section __ex_table,"a";	\
33	.long 99b - .;			\
34	lda $31, $exception-99b($31); 	\
35	.previous
36
37	.set noat
38	.set noreorder
39	.align 4
40
41	.globl __do_clear_user
42	.ent __do_clear_user
43	.frame	$30, 0, $28
44	.prologue 0
45
46$loop:
47	and	$1, 3, $4	# e0    :
48	beq	$4, 1f		# .. e1 :
49
500:	EX( stq_u $31, 0($6) )	# e0    : zero one word
51	subq	$0, 8, $0	# .. e1 :
52	subq	$4, 1, $4	# e0    :
53	addq	$6, 8, $6	# .. e1 :
54	bne	$4, 0b		# e1    :
55	unop			#       :
56
571:	bic	$1, 3, $1	# e0    :
58	beq	$1, $tail	# .. e1 :
59
602:	EX( stq_u $31, 0($6) )	# e0    : zero four words
61	subq	$0, 8, $0	# .. e1 :
62	EX( stq_u $31, 8($6) )	# e0    :
63	subq	$0, 8, $0	# .. e1 :
64	EX( stq_u $31, 16($6) )	# e0    :
65	subq	$0, 8, $0	# .. e1 :
66	EX( stq_u $31, 24($6) )	# e0    :
67	subq	$0, 8, $0	# .. e1 :
68	subq	$1, 4, $1	# e0    :
69	addq	$6, 32, $6	# .. e1 :
70	bne	$1, 2b		# e1    :
71
72$tail:
73	bne	$2, 1f		# e1    : is there a tail to do?
74	ret	$31, ($28), 1	# .. e1 :
75
761:	EX( ldq_u $5, 0($6) )	# e0    :
77	clr	$0		# .. e1 :
78	nop			# e1    :
79	mskqh	$5, $0, $5	# e0    :
80	EX( stq_u $5, 0($6) )	# e0    :
81	ret	$31, ($28), 1	# .. e1 :
82
83__do_clear_user:
84	and	$6, 7, $4	# e0    : find dest misalignment
85	beq	$0, $zerolength # .. e1 :
86	addq	$0, $4, $1	# e0    : bias counter
87	and	$1, 7, $2	# e1    : number of bytes in tail
88	srl	$1, 3, $1	# e0    :
89	beq	$4, $loop	# .. e1 :
90
91	EX( ldq_u $5, 0($6) )	# e0    : load dst word to mask back in
92	beq	$1, $oneword	# .. e1 : sub-word store?
93
94	mskql	$5, $6, $5	# e0    : take care of misaligned head
95	addq	$6, 8, $6	# .. e1 :
96	EX( stq_u $5, -8($6) )	# e0    :
97	addq	$0, $4, $0	# .. e1 : bytes left -= 8 - misalignment
98	subq	$1, 1, $1	# e0    :
99	subq	$0, 8, $0	# .. e1 :
100	br	$loop		# e1    :
101	unop			#       :
102
103$oneword:
104	mskql	$5, $6, $4	# e0    :
105	mskqh	$5, $2, $5	# e0    :
106	or	$5, $4, $5	# e1    :
107	EX( stq_u $5, 0($6) )	# e0    :
108	clr	$0		# .. e1 :
109
110$zerolength:
111$exception:
112	ret	$31, ($28), 1	# .. e1 :
113
114	.end __do_clear_user
115	EXPORT_SYMBOL(__do_clear_user)
116