summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub/asm
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stub/asm')
-rw-r--r--utils/hwstub/stub/asm/mips/memcpy.S153
-rw-r--r--utils/hwstub/stub/asm/mips/memset.S239
2 files changed, 392 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
diff --git a/utils/hwstub/stub/asm/mips/memset.S b/utils/hwstub/stub/asm/mips/memset.S
new file mode 100644
index 0000000000..8db76d9123
--- /dev/null
+++ b/utils/hwstub/stub/asm/mips/memset.S
@@ -0,0 +1,239 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * This file was originally part of the Linux/MIPS GNU C Library
11 * Copyright (C) 1998 by Ralf Baechle
12 * Adapted for Rockbox by Maurus Cuelenaere, 2009
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include "config.h"
25#include "mips.h"
26
27#define FILL256(dst, offset, val) \
28 sw val, (offset + 0x00)(dst); \
29 sw val, (offset + 0x04)(dst); \
30 sw val, (offset + 0x08)(dst); \
31 sw val, (offset + 0x0c)(dst); \
32 sw val, (offset + 0x10)(dst); \
33 sw val, (offset + 0x14)(dst); \
34 sw val, (offset + 0x18)(dst); \
35 sw val, (offset + 0x1c)(dst); \
36 sw val, (offset + 0x20)(dst); \
37 sw val, (offset + 0x24)(dst); \
38 sw val, (offset + 0x28)(dst); \
39 sw val, (offset + 0x2c)(dst); \
40 sw val, (offset + 0x30)(dst); \
41 sw val, (offset + 0x34)(dst); \
42 sw val, (offset + 0x38)(dst); \
43 sw val, (offset + 0x3c)(dst); \
44 sw val, (offset + 0x40)(dst); \
45 sw val, (offset + 0x44)(dst); \
46 sw val, (offset + 0x48)(dst); \
47 sw val, (offset + 0x4c)(dst); \
48 sw val, (offset + 0x50)(dst); \
49 sw val, (offset + 0x54)(dst); \
50 sw val, (offset + 0x58)(dst); \
51 sw val, (offset + 0x5c)(dst); \
52 sw val, (offset + 0x60)(dst); \
53 sw val, (offset + 0x64)(dst); \
54 sw val, (offset + 0x68)(dst); \
55 sw val, (offset + 0x6c)(dst); \
56 sw val, (offset + 0x70)(dst); \
57 sw val, (offset + 0x74)(dst); \
58 sw val, (offset + 0x78)(dst); \
59 sw val, (offset + 0x7c)(dst); \
60 sw val, (offset + 0x80)(dst); \
61 sw val, (offset + 0x84)(dst); \
62 sw val, (offset + 0x88)(dst); \
63 sw val, (offset + 0x8c)(dst); \
64 sw val, (offset + 0x90)(dst); \
65 sw val, (offset + 0x94)(dst); \
66 sw val, (offset + 0x98)(dst); \
67 sw val, (offset + 0x9c)(dst); \
68 sw val, (offset + 0xa0)(dst); \
69 sw val, (offset + 0xa4)(dst); \
70 sw val, (offset + 0xa8)(dst); \
71 sw val, (offset + 0xac)(dst); \
72 sw val, (offset + 0xb0)(dst); \
73 sw val, (offset + 0xb4)(dst); \
74 sw val, (offset + 0xb8)(dst); \
75 sw val, (offset + 0xbc)(dst); \
76 sw val, (offset + 0xc0)(dst); \
77 sw val, (offset + 0xc4)(dst); \
78 sw val, (offset + 0xc8)(dst); \
79 sw val, (offset + 0xcc)(dst); \
80 sw val, (offset + 0xd0)(dst); \
81 sw val, (offset + 0xd4)(dst); \
82 sw val, (offset + 0xd8)(dst); \
83 sw val, (offset + 0xdc)(dst); \
84 sw val, (offset + 0xe0)(dst); \
85 sw val, (offset + 0xe4)(dst); \
86 sw val, (offset + 0xe8)(dst); \
87 sw val, (offset + 0xec)(dst); \
88 sw val, (offset + 0xf0)(dst); \
89 sw val, (offset + 0xf4)(dst); \
90 sw val, (offset + 0xf8)(dst); \
91 sw val, (offset + 0xfc)(dst);
92
93#define FILL128(dst, offset, val) \
94 sw val, (offset + 0x00)(dst); \
95 sw val, (offset + 0x04)(dst); \
96 sw val, (offset + 0x08)(dst); \
97 sw val, (offset + 0x0c)(dst); \
98 sw val, (offset + 0x10)(dst); \
99 sw val, (offset + 0x14)(dst); \
100 sw val, (offset + 0x18)(dst); \
101 sw val, (offset + 0x1c)(dst); \
102 sw val, (offset + 0x20)(dst); \
103 sw val, (offset + 0x24)(dst); \
104 sw val, (offset + 0x28)(dst); \
105 sw val, (offset + 0x2c)(dst); \
106 sw val, (offset + 0x30)(dst); \
107 sw val, (offset + 0x34)(dst); \
108 sw val, (offset + 0x38)(dst); \
109 sw val, (offset + 0x3c)(dst); \
110 sw val, (offset + 0x40)(dst); \
111 sw val, (offset + 0x44)(dst); \
112 sw val, (offset + 0x48)(dst); \
113 sw val, (offset + 0x4c)(dst); \
114 sw val, (offset + 0x50)(dst); \
115 sw val, (offset + 0x54)(dst); \
116 sw val, (offset + 0x58)(dst); \
117 sw val, (offset + 0x5c)(dst); \
118 sw val, (offset + 0x60)(dst); \
119 sw val, (offset + 0x64)(dst); \
120 sw val, (offset + 0x68)(dst); \
121 sw val, (offset + 0x6c)(dst); \
122 sw val, (offset + 0x70)(dst); \
123 sw val, (offset + 0x74)(dst); \
124 sw val, (offset + 0x78)(dst); \
125 sw val, (offset + 0x7c)(dst);
126
127#define FILL64(dst, offset, val) \
128 sw val, (offset + 0x00)(dst); \
129 sw val, (offset + 0x04)(dst); \
130 sw val, (offset + 0x08)(dst); \
131 sw val, (offset + 0x0c)(dst); \
132 sw val, (offset + 0x10)(dst); \
133 sw val, (offset + 0x14)(dst); \
134 sw val, (offset + 0x18)(dst); \
135 sw val, (offset + 0x1c)(dst); \
136 sw val, (offset + 0x20)(dst); \
137 sw val, (offset + 0x24)(dst); \
138 sw val, (offset + 0x28)(dst); \
139 sw val, (offset + 0x2c)(dst); \
140 sw val, (offset + 0x30)(dst); \
141 sw val, (offset + 0x34)(dst); \
142 sw val, (offset + 0x38)(dst); \
143 sw val, (offset + 0x3c)(dst);
144
145#define FILL32(dst, offset, val) \
146 sw val, (offset + 0x00)(dst); \
147 sw val, (offset + 0x04)(dst); \
148 sw val, (offset + 0x08)(dst); \
149 sw val, (offset + 0x0c)(dst); \
150 sw val, (offset + 0x10)(dst); \
151 sw val, (offset + 0x14)(dst); \
152 sw val, (offset + 0x18)(dst); \
153 sw val, (offset + 0x1c)(dst);
154
155#define FILL 64
156#define F_FILL FILL64
157
158
159#ifdef ROCKBOX_BIG_ENDIAN
160# define SWHI swl /* high part is left in big-endian */
161#else
162# define SWHI swr /* high part is right in little-endian */
163#endif
164
165/*
166 * memset(void *s, int c, size_t n)
167 *
168 * a0: start of area to clear
169 * a1: char to fill with
170 * a2: size of area to clear
171 */
172 .section .icode, "ax", %progbits
173
174 .global memset
175 .type memset, %function
176
177 .set noreorder
178 .align 5
179memset:
180 beqz a1, 1f
181 move v0, a0 /* result */
182
183 andi a1, 0xff /* spread fillword */
184 sll t1, a1, 8
185 or a1, t1
186 sll t1, a1, 16
187 or a1, t1
1881:
189
190 sltiu t0, a2, 4 /* very small region? */
191 bnez t0, small_memset
192 andi t0, a0, 3 /* aligned? */
193
194 beqz t0, 1f
195 subu t0, 4 /* alignment in bytes */
196
197 SWHI a1, (a0) /* make word aligned */
198 subu a0, t0 /* word align ptr */
199 addu a2, t0 /* correct size */
200
2011: ori t1, a2, (FILL-1) /* # of full blocks */
202 xori t1, (FILL-1)
203 beqz t1, memset_partial /* no block to fill */
204 andi t0, a2, (FILL-4)
205
206 addu t1, a0 /* end address */
207 .set reorder
2081: addiu a0, FILL
209 F_FILL( a0, -FILL, a1 )
210 bne t1, a0, 1b
211 .set noreorder
212
213memset_partial:
214 la t1, 2f /* where to start */
215 subu t1, t0
216 jr t1
217 addu a0, t0 /* dest ptr */
218
219 F_FILL( a0, -FILL, a1 ) /* ... but first do words ... */
2202: andi a2, 3 /* 0 <= n <= 3 to go */
221
222 beqz a2, 1f
223 addu a0, a2 /* What's left */
224 SWHI a1, -1(a0)
2251: jr ra
226 move a2, zero
227
228small_memset:
229 beqz a2, 2f
230 addu t1, a0, a2
231
2321: addiu a0, 1 /* fill bytewise */
233 bne t1, a0, 1b
234 sb a1, -1(a0)
235
2362: jr ra /* done */
237 move a2, zero
238
239 .set reorder