1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
11 * This file was originally part of the GNU C Library
12 * Contributed to glibc by Hartvig Ekner <hartvige@mips.com>, 2002
13 * Adapted for Rockbox by Maurus Cuelenaere, 2009
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
23 ****************************************************************************/
28 /* void *memcpy(void *s1, const void *s2, size_t n); */
30 #ifdef ROCKBOX_BIG_ENDIAN
31 # define LWHI lwl /* high part is left in big-endian */
32 # define SWHI swl /* high part is left in big-endian */
33 # define LWLO lwr /* low part is right in big-endian */
34 # define SWLO swr /* low part is right in big-endian */
36 # define LWHI lwr /* high part is right in little-endian */
37 # define SWHI swr /* high part is right in little-endian */
38 # define LWLO lwl /* low part is left in little-endian */
39 # define SWLO swl /* low part is left in little-endian */
42 .section .icode, "ax", %progbits
45 .type memcpy, %function
50 slti t0, a2, 8 # Less than 8?
52 move v0, a0 # Setup exit value before too late
54 xor t0, a1, a0 # Find a0/a1 displacement
56 bne t0, zero, shift # Go handle the unaligned case
58 andi t1, 0x3 # a0/a1 are aligned, but are we
59 beq t1, zero, chk8w # starting in the middle of a word?
61 LWHI t0, 0(a1) # Yes we are... take care of that
67 andi t0, a2, 0x1f # 32 or more bytes left?
70 addu a3, a1 # a3 = end address of loop
71 move a2, t0 # a2 = what will be left after loop
73 lw t0, 0(a1) # Loop taking 8 words at a time
94 andi t0, a2, 0x3 # 4 or more bytes left?
96 subu a3, a2, t0 # Yes, handle them one word at a time
97 addu a3, a1 # a3 again end address
107 blez a2, lst8e # Handle last 8 bytes, one at a time
120 subu a3, zero, a0 # Src and Dest unaligned
121 andi a3, 0x3 # (unoptimized case...)
123 subu a2, a3 # a2 = bytes left
124 LWHI t0, 0(a1) # Take care of first odd part
134 LWHI t1, 0(a1) # Limp through, word by word
140 b last8 # Handle anything which may be left