]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
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.. | |
1da177e4 LT |
12 | */ |
13 | ||
00fc0e0d AV |
14 | #include <asm/export.h> |
15 | ||
1da177e4 LT |
16 | /* Allow an exception for an insn; exit if we get one. */ |
17 | #define EXI(x,y...) \ | |
18 | 99: x,##y; \ | |
19 | .section __ex_table,"a"; \ | |
20 | .long 99b - .; \ | |
21 | lda $31, $exitin-99b($31); \ | |
22 | .previous | |
23 | ||
24 | #define EXO(x,y...) \ | |
25 | 99: x,##y; \ | |
26 | .section __ex_table,"a"; \ | |
27 | .long 99b - .; \ | |
28 | lda $31, $exitout-99b($31); \ | |
29 | .previous | |
30 | ||
31 | .set noat | |
32 | .align 4 | |
33 | .globl __copy_user | |
34 | .ent __copy_user | |
35 | __copy_user: | |
36 | .prologue 0 | |
4606f68f | 37 | mov $18,$0 |
85250231 | 38 | and $16,7,$3 |
1da177e4 LT |
39 | beq $0,$35 |
40 | beq $3,$36 | |
41 | subq $3,8,$3 | |
42 | .align 4 | |
43 | $37: | |
85250231 AV |
44 | EXI( ldq_u $1,0($17) ) |
45 | EXO( ldq_u $2,0($16) ) | |
46 | extbl $1,$17,$1 | |
47 | mskbl $2,$16,$2 | |
48 | insbl $1,$16,$1 | |
1da177e4 LT |
49 | addq $3,1,$3 |
50 | bis $1,$2,$1 | |
85250231 | 51 | EXO( stq_u $1,0($16) ) |
1da177e4 | 52 | subq $0,1,$0 |
85250231 AV |
53 | addq $16,1,$16 |
54 | addq $17,1,$17 | |
1da177e4 LT |
55 | beq $0,$41 |
56 | bne $3,$37 | |
57 | $36: | |
85250231 | 58 | and $17,7,$1 |
1da177e4 LT |
59 | bic $0,7,$4 |
60 | beq $1,$43 | |
61 | beq $4,$48 | |
85250231 | 62 | EXI( ldq_u $3,0($17) ) |
1da177e4 LT |
63 | .align 4 |
64 | $50: | |
85250231 | 65 | EXI( ldq_u $2,8($17) ) |
1da177e4 | 66 | subq $4,8,$4 |
85250231 AV |
67 | extql $3,$17,$3 |
68 | extqh $2,$17,$1 | |
1da177e4 | 69 | bis $3,$1,$1 |
85250231 AV |
70 | EXO( stq $1,0($16) ) |
71 | addq $17,8,$17 | |
1da177e4 | 72 | subq $0,8,$0 |
85250231 | 73 | addq $16,8,$16 |
1da177e4 LT |
74 | bis $2,$2,$3 |
75 | bne $4,$50 | |
76 | $48: | |
77 | beq $0,$41 | |
78 | .align 4 | |
79 | $57: | |
85250231 AV |
80 | EXI( ldq_u $1,0($17) ) |
81 | EXO( ldq_u $2,0($16) ) | |
82 | extbl $1,$17,$1 | |
83 | mskbl $2,$16,$2 | |
84 | insbl $1,$16,$1 | |
1da177e4 | 85 | bis $1,$2,$1 |
85250231 | 86 | EXO( stq_u $1,0($16) ) |
1da177e4 | 87 | subq $0,1,$0 |
85250231 AV |
88 | addq $16,1,$16 |
89 | addq $17,1,$17 | |
1da177e4 LT |
90 | bne $0,$57 |
91 | br $31,$41 | |
92 | .align 4 | |
93 | $43: | |
94 | beq $4,$65 | |
95 | .align 4 | |
96 | $66: | |
85250231 | 97 | EXI( ldq $1,0($17) ) |
1da177e4 | 98 | subq $4,8,$4 |
85250231 AV |
99 | EXO( stq $1,0($16) ) |
100 | addq $17,8,$17 | |
1da177e4 | 101 | subq $0,8,$0 |
85250231 | 102 | addq $16,8,$16 |
1da177e4 LT |
103 | bne $4,$66 |
104 | $65: | |
105 | beq $0,$41 | |
85250231 AV |
106 | EXI( ldq $2,0($17) ) |
107 | EXO( ldq $1,0($16) ) | |
1da177e4 LT |
108 | mskql $2,$0,$2 |
109 | mskqh $1,$0,$1 | |
110 | bis $2,$1,$2 | |
85250231 | 111 | EXO( stq $2,0($16) ) |
1da177e4 LT |
112 | bis $31,$31,$0 |
113 | $41: | |
114 | $35: | |
1da177e4 | 115 | $exitin: |
085354f9 | 116 | $exitout: |
85250231 | 117 | ret $31,($26),1 |
1da177e4 LT |
118 | |
119 | .end __copy_user | |
00fc0e0d | 120 | EXPORT_SYMBOL(__copy_user) |