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 134EXPORT_SYMBOL(__copy_user) 135