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