1 /* $Id: copy_page.S,v 1.8 2003/08/25 17:03:10 lethal Exp $
3 * copy_page, __copy_user_page, __copy_user implementation of SuperH
5 * Copyright (C) 2001 Niibe Yutaka & Kaz Kojima
6 * Copyright (C) 2002 Toshinobu Sugioka
9 #include <linux/linkage.h>
16 * void copy_page_slow(void *to, void *from)
20 * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
44 #if defined(CONFIG_CPU_SH3)
46 #elif defined(CONFIG_CPU_SH4)
58 #if defined(CONFIG_CPU_SH4)
71 #if defined(CONFIG_CPU_SH4)
74 * @to: P1 address (with same color)
76 * @orig_to: P1 address
78 * void __copy_user_page(void *to, void *from, void *orig_to)
82 * r0, r1, r2, r3, r4, r5, r6, r7 --- scratch
88 ENTRY(__copy_user_page)
134 * __kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
135 * Return the number of bytes NOT copied
138 9999: __VA_ARGS__ ; \
139 .section __ex_table, "a"; \
140 .long 9999b, 6000f ; \
143 tst r6,r6 ! Check explicitly for zero
146 mov #0,r0 ! normal return
152 add r6,r3 ! last destination address
153 mov #12,r0 ! Check if small number of bytes
159 neg r5,r0 ! Calculate bytes needed to align source
167 ! Copy bytes to align source
176 mov r6,r2 ! Calculate number of longwords to copy
181 mov r4,r0 ! Jump to appropriate routine
214 EX( mov.l r8,@(4,r4) )
215 EX( mov.l r9,@(8,r4) )
216 EX( mov.l r10,@(12,r4) )
222 EX( mov.l r0,@(16,r4) )
223 EX( mov.l r8,@(20,r4) )
224 EX( mov.l r9,@(24,r4) )
225 EX( mov.l r10,@(28,r4) )
252 #ifdef __LITTLE_ENDIAN__
266 EX( mov.l r1,@(4,r4) )
267 EX( mov.l r8,@(8,r4) )
268 EX( mov.l r9,@(12,r4) )
277 EX( mov.l r10,@(16,r4) )
278 EX( mov.l r1,@(20,r4) )
279 EX( mov.l r8,@(24,r4) )
280 EX( mov.w r0,@(28,r4) )
284 EX( mov.l @(28,r5),r0 )
285 EX( mov.l @(24,r5),r8 )
286 EX( mov.l @(20,r5),r9 )
287 EX( mov.l @(16,r5),r10 )
288 EX( mov.w r0,@(30,r4) )
293 EX( mov.l r0,@(28,r4) )
294 EX( mov.l r8,@(24,r4) )
295 EX( mov.l r9,@(20,r4) )
297 EX( mov.l @(12,r5),r0 )
298 EX( mov.l @(8,r5),r8 )
300 EX( mov.l @(4,r5),r9 )
306 EX( mov.l r0,@(12,r4) )
307 EX( mov.l r8,@(8,r4) )
309 EX( mov.l r9,@(4,r4) )
310 EX( mov.w r0,@(2,r4) )
319 1: ! Read longword, write two words per iteration
322 #ifdef __LITTLE_ENDIAN__
325 EX( mov.w r0,@(2,r4) )
327 EX( mov.w r0,@(2,r4) )
337 ! Destination = 01 or 11
341 ! Read longword, write byte, word, byte per iteration
344 #ifdef __LITTLE_ENDIAN__
350 EX( mov.b r0,@(2,r4) )
354 EX( mov.b r0,@(3,r4) )
364 ! Cleanup last few bytes
380 mov #0,r0 ! normal return
384 .section .fixup, "ax"