1/* copy_in_user.S: Copy from userspace to userspace. 2 * 3 * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com) 4 */ 5 6#include <linux/linkage.h> 7#include <asm/asi.h> 8#include <asm/export.h> 9 10#define XCC xcc 11 12#define EX(x,y) \ 1398: x,y; \ 14 .section __ex_table,"a";\ 15 .align 4; \ 16 .word 98b, __retl_one; \ 17 .text; \ 18 .align 4; 19 20 .register %g2,#scratch 21 .register %g3,#scratch 22 23 .text 24 .align 32 25 26 /* Don't try to get too fancy here, just nice and 27 * simple. This is predominantly used for well aligned 28 * small copies in the compat layer. It is also used 29 * to copy register windows around during thread cloning. 30 */ 31 32ENTRY(___copy_in_user) /* %o0=dst, %o1=src, %o2=len */ 33 cmp %o2, 0 34 be,pn %XCC, 85f 35 or %o0, %o1, %o3 36 cmp %o2, 16 37 bleu,a,pn %XCC, 80f 38 or %o3, %o2, %o3 39 40 /* 16 < len <= 64 */ 41 andcc %o3, 0x7, %g0 42 bne,pn %XCC, 90f 43 nop 44 45 andn %o2, 0x7, %o4 46 and %o2, 0x7, %o2 471: subcc %o4, 0x8, %o4 48 EX(ldxa [%o1] %asi, %o5) 49 EX(stxa %o5, [%o0] %asi) 50 add %o1, 0x8, %o1 51 bgu,pt %XCC, 1b 52 add %o0, 0x8, %o0 53 andcc %o2, 0x4, %g0 54 be,pt %XCC, 1f 55 nop 56 sub %o2, 0x4, %o2 57 EX(lduwa [%o1] %asi, %o5) 58 EX(stwa %o5, [%o0] %asi) 59 add %o1, 0x4, %o1 60 add %o0, 0x4, %o0 611: cmp %o2, 0 62 be,pt %XCC, 85f 63 nop 64 ba,pt %xcc, 90f 65 nop 66 6780: /* 0 < len <= 16 */ 68 andcc %o3, 0x3, %g0 69 bne,pn %XCC, 90f 70 nop 71 7282: 73 subcc %o2, 4, %o2 74 EX(lduwa [%o1] %asi, %g1) 75 EX(stwa %g1, [%o0] %asi) 76 add %o1, 4, %o1 77 bgu,pt %XCC, 82b 78 add %o0, 4, %o0 79 8085: retl 81 clr %o0 82 83 .align 32 8490: 85 subcc %o2, 1, %o2 86 EX(lduba [%o1] %asi, %g1) 87 EX(stba %g1, [%o0] %asi) 88 add %o1, 1, %o1 89 bgu,pt %XCC, 90b 90 add %o0, 1, %o0 91 retl 92 clr %o0 93ENDPROC(___copy_in_user) 94EXPORT_SYMBOL(___copy_in_user) 95