summaryrefslogtreecommitdiff
path: root/firmware/asm/mips/memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/asm/mips/memcpy.S')
-rw-r--r--firmware/asm/mips/memcpy.S143
1 files changed, 143 insertions, 0 deletions
diff --git a/firmware/asm/mips/memcpy.S b/firmware/asm/mips/memcpy.S
new file mode 100644
index 0000000000..2e7f245c69
--- /dev/null
+++ b/firmware/asm/mips/memcpy.S
@@ -0,0 +1,143 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
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
14 *
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.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26#include "mips.h"
27
28/* void *memcpy(void *s1, const void *s2, size_t n); */
29
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 */
35#else
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 */
40#endif
41
42 .section .icode, "ax", %progbits
43
44 .global memcpy
45 .type memcpy, %function
46
47 .set noreorder
48
49memcpy:
50 slti t0, a2, 8 # Less than 8?
51 bne t0, zero, last8
52 move v0, a0 # Setup exit value before too late
53
54 xor t0, a1, a0 # Find a0/a1 displacement
55 andi t0, 0x3
56 bne t0, zero, shift # Go handle the unaligned case
57 subu t1, zero, a1
58 andi t1, 0x3 # a0/a1 are aligned, but are we
59 beq t1, zero, chk8w # starting in the middle of a word?
60 subu a2, t1
61 LWHI t0, 0(a1) # Yes we are... take care of that
62 addu a1, t1
63 SWHI t0, 0(a0)
64 addu a0, t1
65
66chk8w:
67 andi t0, a2, 0x1f # 32 or more bytes left?
68 beq t0, a2, chk1w
69 subu a3, a2, t0 # Yes
70 addu a3, a1 # a3 = end address of loop
71 move a2, t0 # a2 = what will be left after loop
72lop8w:
73 lw t0, 0(a1) # Loop taking 8 words at a time
74 lw t1, 4(a1)
75 lw t2, 8(a1)
76 lw t3, 12(a1)
77 lw t4, 16(a1)
78 lw t5, 20(a1)
79 lw t6, 24(a1)
80 lw t7, 28(a1)
81 addiu a0, 32
82 addiu a1, 32
83 sw t0, -32(a0)
84 sw t1, -28(a0)
85 sw t2, -24(a0)
86 sw t3, -20(a0)
87 sw t4, -16(a0)
88 sw t5, -12(a0)
89 sw t6, -8(a0)
90 bne a1, a3, lop8w
91 sw t7, -4(a0)
92
93chk1w:
94 andi t0, a2, 0x3 # 4 or more bytes left?
95 beq t0, a2, last8
96 subu a3, a2, t0 # Yes, handle them one word at a time
97 addu a3, a1 # a3 again end address
98 move a2, t0
99lop1w:
100 lw t0, 0(a1)
101 addiu a0, 4
102 addiu a1, 4
103 bne a1, a3, lop1w
104 sw t0, -4(a0)
105
106last8:
107 blez a2, lst8e # Handle last 8 bytes, one at a time
108 addu a3, a2, a1
109lst8l:
110 lb t0, 0(a1)
111 addiu a0, 1
112 addiu a1, 1
113 bne a1, a3, lst8l
114 sb t0, -1(a0)
115lst8e:
116 jr ra # Bye, bye
117 nop
118
119shift:
120 subu a3, zero, a0 # Src and Dest unaligned
121 andi a3, 0x3 # (unoptimized case...)
122 beq a3, zero, shft1
123 subu a2, a3 # a2 = bytes left
124 LWHI t0, 0(a1) # Take care of first odd part
125 LWLO t0, 3(a1)
126 addu a1, a3
127 SWHI t0, 0(a0)
128 addu a0, a3
129shft1:
130 andi t0, a2, 0x3
131 subu a3, a2, t0
132 addu a3, a1
133shfth:
134 LWHI t1, 0(a1) # Limp through, word by word
135 LWLO t1, 3(a1)
136 addiu a0, 4
137 addiu a1, 4
138 bne a1, a3, shfth
139 sw t1, -4(a0)
140 b last8 # Handle anything which may be left
141 move a2, t0
142
143 .set reorder