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