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