blob: 509f62b6531102b539e61f11519ac4d49da02fe9 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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
Al Viro00fc0e02016-01-11 09:51:29 -050029#include <asm/export.h>
30
Linus Torvalds1da177e2005-04-16 15:20:36 -070031/* 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:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129$exitin:
Al Viro085354f2016-09-10 16:21:34 -0400130$exitout:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131 ret $31,($28),1
132
133 .end __copy_user
Al Viro00fc0e02016-01-11 09:51:29 -0500134EXPORT_SYMBOL(__copy_user)