1 /* U3copy_in_user.S: UltraSparc-III optimized memcpy.
3 * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
6 #include <asm/visasm.h>
9 #include <asm/spitfire.h>
13 #define EXNV(x,y,a,b) \
19 .section __ex_table; \
24 #define EXNV1(x,y,a,b) \
31 .section __ex_table; \
36 #define EXNV4(x,y,a,b) \
43 .section __ex_table; \
48 #define EXNV8(x,y,a,b) \
55 .section __ex_table; \
61 .register %g2,#scratch
62 .register %g3,#scratch
67 /* Don't try to get too fancy here, just nice and
68 * simple. This is predominantly used for well aligned
69 * small copies in the compat layer. It is also used
70 * to copy register windows around during thread cloning.
74 U3copy_in_user: /* %o0=dst, %o1=src, %o2=len */
75 /* Writing to %asi is _expensive_ so we hardcode it.
76 * Reading %asi to check for KERNEL_DS is comparatively
81 bne,pn %icc, U3memcpy_user_stub
88 bleu,a,pn %XCC, small_copy
91 medium_copy: /* 16 < len <= 64 */
93 bne,pn %XCC, small_copy_unaligned
99 1: subcc %o4, 0x8, %o4
100 EXNV8(ldxa [%o1] %asi, %o5, add %o4, %o2)
101 EXNV8(stxa %o5, [%o1 + %o3] ASI_AIUS, add %o4, %o2)
108 EXNV4(lduwa [%o1] %asi, %o5, add %o4, %o2)
109 EXNV4(stwa %o5, [%o1 + %o3] ASI_AIUS, add %o4, %o2)
114 ba,pt %xcc, small_copy_unaligned
117 small_copy: /* 0 < len <= 16 */
119 bne,pn %XCC, small_copy_unaligned
124 EXNV4(lduwa [%o1] %asi, %g1, add %o2, %g0)
125 EXNV4(stwa %g1, [%o1 + %o3] ASI_AIUS, add %o2, %g0)
126 bgu,pt %XCC, small_copy_aligned
133 small_copy_unaligned:
135 EXNV1(lduba [%o1] %asi, %g1, add %o2, %g0)
136 EXNV1(stba %g1, [%o1 + %o3] ASI_AIUS, add %o2, %g0)
137 bgu,pt %XCC, small_copy_unaligned