aboutsummaryrefslogtreecommitdiffstats
path: root/arch/alpha/lib/clear_user.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/alpha/lib/clear_user.S')
-rw-r--r--arch/alpha/lib/clear_user.S113
1 files changed, 113 insertions, 0 deletions
diff --git a/arch/alpha/lib/clear_user.S b/arch/alpha/lib/clear_user.S
new file mode 100644
index 000000000000..8860316c1957
--- /dev/null
+++ b/arch/alpha/lib/clear_user.S
@@ -0,0 +1,113 @@
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