Merge branch 'linux-4.15' of git://github.com/skeggsb/linux into drm-fixes
[sfrench/cifs-2.6.git] / arch / alpha / lib / clear_user.S
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 <asm/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)