summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub/asm/mips/memcpy.S
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stub/asm/mips/memcpy.S')
-rw-r--r--utils/hwstub/stub/asm/mips/memcpy.S153
1 files changed, 153 insertions, 0 deletions
diff --git a/utils/hwstub/stub/asm/mips/memcpy.S b/utils/hwstub/stub/asm/mips/memcpy.S
new file mode 100644
index 0000000000..0477dcd0fb
--- /dev/null
+++ b/utils/hwstub/stub/asm/mips/memcpy.S
@@ -0,0 +1,153 @@
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 * memmove() adapted after linux kernel by Marcin Bukat, 2014
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
20 *
21 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22 * KIND, either express or implied.
23 *
24 ****************************************************************************/
25
26#include "config.h"
27#include "mips.h"
28
29/* void *memcpy(void *s1, const void *s2, size_t n); */
30
31#ifdef ROCKBOX_BIG_ENDIAN
32# define LWHI lwl /* high part is left in big-endian */
33# define SWHI swl /* high part is left in big-endian */
34# define LWLO lwr /* low part is right in big-endian */
35# define SWLO swr /* low part is right in big-endian */
36#else
37# define LWHI lwr /* high part is right in little-endian */
38# define SWHI swr /* high part is right in little-endian */
39# define LWLO lwl /* low part is left in little-endian */
40# define SWLO swl /* low part is left in little-endian */
41#endif
42
43 .section .icode, "ax", %progbits
44
45 .global memcpy
46 .type memcpy, %function
47 .global mempcpy
48 .type mempcpy, %function
49
50 .set noreorder
51mempcpy:
52 slti t0, a2, 8 # Less than 8?
53 bne t0, zero, last8
54 addu v0, a0, a2 # exit value = s1 + n
55 b 1f
56 xor t0, a1, a0 # Find a0/a1 displacement (fill delay)
57
58memcpy:
59 slti t0, a2, 8 # Less than 8?
60 bne t0, zero, last8
61 move v0, a0 # Setup exit value before too late
62
63 xor t0, a1, a0 # Find a0/a1 displacement
64
651: andi t0, 0x3
66 bne t0, zero, shift # Go handle the unaligned case
67 subu t1, zero, a1
68 andi t1, 0x3 # a0/a1 are aligned, but are we
69 beq t1, zero, chk8w # starting in the middle of a word?
70 subu a2, t1
71 LWHI t0, 0(a1) # Yes we are... take care of that
72 addu a1, t1
73 SWHI t0, 0(a0)
74 addu a0, t1
75
76chk8w:
77 andi t0, a2, 0x1f # 32 or more bytes left?
78 beq t0, a2, chk1w
79 subu a3, a2, t0 # Yes
80 addu a3, a1 # a3 = end address of loop
81 move a2, t0 # a2 = what will be left after loop
82lop8w:
83 lw t0, 0(a1) # Loop taking 8 words at a time
84 lw t1, 4(a1)
85 lw t2, 8(a1)
86 lw t3, 12(a1)
87 lw t4, 16(a1)
88 lw t5, 20(a1)
89 lw t6, 24(a1)
90 lw t7, 28(a1)
91 addiu a0, 32
92 addiu a1, 32
93 sw t0, -32(a0)
94 sw t1, -28(a0)
95 sw t2, -24(a0)
96 sw t3, -20(a0)
97 sw t4, -16(a0)
98 sw t5, -12(a0)
99 sw t6, -8(a0)
100 bne a1, a3, lop8w
101 sw t7, -4(a0)
102
103chk1w:
104 andi t0, a2, 0x3 # 4 or more bytes left?
105 beq t0, a2, last8
106 subu a3, a2, t0 # Yes, handle them one word at a time
107 addu a3, a1 # a3 again end address
108 move a2, t0
109lop1w:
110 lw t0, 0(a1)
111 addiu a0, 4
112 addiu a1, 4
113 bne a1, a3, lop1w
114 sw t0, -4(a0)
115
116last8:
117 blez a2, lst8e # Handle last 8 bytes, one at a time
118 addu a3, a2, a1
119lst8l:
120 lb t0, 0(a1)
121 addiu a0, 1
122 addiu a1, 1
123 bne a1, a3, lst8l
124 sb t0, -1(a0)
125lst8e:
126 jr ra # Bye, bye
127 nop
128
129shift:
130 subu a3, zero, a0 # Src and Dest unaligned
131 andi a3, 0x3 # (unoptimized case...)
132 beq a3, zero, shft1
133 subu a2, a3 # a2 = bytes left
134 LWHI t0, 0(a1) # Take care of first odd part
135 LWLO t0, 3(a1)
136 addu a1, a3
137 SWHI t0, 0(a0)
138 addu a0, a3
139shft1:
140 andi t0, a2, 0x3
141 subu a3, a2, t0
142 addu a3, a1
143shfth:
144 LWHI t1, 0(a1) # Limp through, word by word
145 LWLO t1, 3(a1)
146 addiu a0, 4
147 addiu a1, 4
148 bne a1, a3, shfth
149 sw t1, -4(a0)
150 b last8 # Handle anything which may be left
151 move a2, t0
152
153 .set reorder