Merge remote-tracking branch 'asoc/fix/intel' into asoc-linus
[sfrench/cifs-2.6.git] / arch / alpha / lib / copy_user.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * arch/alpha/lib/copy_user.S
4  *
5  * Copy to/from user space, handling exceptions as we go..  This
6  * isn't exactly pretty.
7  *
8  * This is essentially the same as "memcpy()", but with a few twists.
9  * Notably, we have to make sure that $0 is always up-to-date and
10  * contains the right "bytes left to copy" value (and that it is updated
11  * only _after_ a successful copy). There is also some rather minor
12  * exception setup stuff..
13  */
14
15 #include <asm/export.h>
16
17 /* Allow an exception for an insn; exit if we get one.  */
18 #define EXI(x,y...)                     \
19         99: x,##y;                      \
20         .section __ex_table,"a";        \
21         .long 99b - .;                  \
22         lda $31, $exitin-99b($31);      \
23         .previous
24
25 #define EXO(x,y...)                     \
26         99: x,##y;                      \
27         .section __ex_table,"a";        \
28         .long 99b - .;                  \
29         lda $31, $exitout-99b($31);     \
30         .previous
31
32         .set noat
33         .align 4
34         .globl __copy_user
35         .ent __copy_user
36 __copy_user:
37         .prologue 0
38         mov $18,$0
39         and $16,7,$3
40         beq $0,$35
41         beq $3,$36
42         subq $3,8,$3
43         .align 4
44 $37:
45         EXI( ldq_u $1,0($17) )
46         EXO( ldq_u $2,0($16) )
47         extbl $1,$17,$1
48         mskbl $2,$16,$2
49         insbl $1,$16,$1
50         addq $3,1,$3
51         bis $1,$2,$1
52         EXO( stq_u $1,0($16) )
53         subq $0,1,$0
54         addq $16,1,$16
55         addq $17,1,$17
56         beq $0,$41
57         bne $3,$37
58 $36:
59         and $17,7,$1
60         bic $0,7,$4
61         beq $1,$43
62         beq $4,$48
63         EXI( ldq_u $3,0($17) )
64         .align 4
65 $50:
66         EXI( ldq_u $2,8($17) )
67         subq $4,8,$4
68         extql $3,$17,$3
69         extqh $2,$17,$1
70         bis $3,$1,$1
71         EXO( stq $1,0($16) )
72         addq $17,8,$17
73         subq $0,8,$0
74         addq $16,8,$16
75         bis $2,$2,$3
76         bne $4,$50
77 $48:
78         beq $0,$41
79         .align 4
80 $57:
81         EXI( ldq_u $1,0($17) )
82         EXO( ldq_u $2,0($16) )
83         extbl $1,$17,$1
84         mskbl $2,$16,$2
85         insbl $1,$16,$1
86         bis $1,$2,$1
87         EXO( stq_u $1,0($16) )
88         subq $0,1,$0
89         addq $16,1,$16
90         addq $17,1,$17
91         bne $0,$57
92         br $31,$41
93         .align 4
94 $43:
95         beq $4,$65
96         .align 4
97 $66:
98         EXI( ldq $1,0($17) )
99         subq $4,8,$4
100         EXO( stq $1,0($16) )
101         addq $17,8,$17
102         subq $0,8,$0
103         addq $16,8,$16
104         bne $4,$66
105 $65:
106         beq $0,$41
107         EXI( ldq $2,0($17) )
108         EXO( ldq $1,0($16) )
109         mskql $2,$0,$2
110         mskqh $1,$0,$1
111         bis $2,$1,$2
112         EXO( stq $2,0($16) )
113         bis $31,$31,$0
114 $41:
115 $35:
116 $exitin:
117 $exitout:
118         ret $31,($26),1
119
120         .end __copy_user
121 EXPORT_SYMBOL(__copy_user)