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