summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-02-22 01:20:45 +0000
committerJens Arnold <amiconn@rockbox.org>2006-02-22 01:20:45 +0000
commiteb65f89f0e1b88e3d7576eee3e490c007d02076d (patch)
tree7415e87f06bc131f362e69d2e25cd0e625d48841
parenta875703e6e0e26cfd4dfd74d56a7d28feb37bdc5 (diff)
downloadrockbox-eb65f89f0e1b88e3d7576eee3e490c007d02076d.tar.gz
rockbox-eb65f89f0e1b88e3d7576eee3e490c007d02076d.zip
Added memset16() for filling memory regions with 16 bit values, needed for upcoming 16 bit LCD driver opts. ASM optimised for coldfire.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8773 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES5
-rwxr-xr-xfirmware/common/memset16.c79
-rwxr-xr-xfirmware/common/memset16_a.S146
-rwxr-xr-xfirmware/include/memory.h27
4 files changed, 257 insertions, 0 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 15a5de8b7c..1a8335e61f 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -45,6 +45,11 @@ common/memcpy.c
45common/memmove.c 45common/memmove.c
46common/memset.c 46common/memset.c
47#endif 47#endif
48#ifdef CPU_COLDFIRE
49common/memset16_a.S
50#else
51common/memset16.c
52#endif
48#ifdef HAVE_LCD_CHARCELLS 53#ifdef HAVE_LCD_CHARCELLS
49drivers/lcd-player-charset.c 54drivers/lcd-player-charset.c
50drivers/lcd-player.c 55drivers/lcd-player.c
diff --git a/firmware/common/memset16.c b/firmware/common/memset16.c
new file mode 100755
index 0000000000..0aee97a169
--- /dev/null
+++ b/firmware/common/memset16.c
@@ -0,0 +1,79 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <string.h>
21#define LBLOCKSIZE (sizeof(long)/2)
22#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
23#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
24
25void *memset16(void *dst, int val, size_t len)
26{
27#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
28 unsigned short *p = (unsigned short *)dst;
29
30 while (len--)
31 *p++ = val;
32
33 return dst;
34#else
35 unsigned short *p = (unsigned short *)dst;
36 unsigned int i;
37 unsigned long buffer;
38 unsigned long *aligned_addr;
39
40 if (!TOO_SMALL(len) && !UNALIGNED(dst))
41 {
42 aligned_addr = (unsigned long *)dst;
43
44 val &= 0xffff;
45 if (LBLOCKSIZE == 2)
46 {
47 buffer = (val << 16) | val;
48 }
49 else
50 {
51 buffer = 0;
52 for (i = 0; i < LBLOCKSIZE; i++)
53 buffer = (buffer << 16) | val;
54 }
55
56 while (len >= LBLOCKSIZE*4)
57 {
58 *aligned_addr++ = buffer;
59 *aligned_addr++ = buffer;
60 *aligned_addr++ = buffer;
61 *aligned_addr++ = buffer;
62 len -= 4*LBLOCKSIZE;
63 }
64
65 while (len >= LBLOCKSIZE)
66 {
67 *aligned_addr++ = buffer;
68 len -= LBLOCKSIZE;
69 }
70
71 p = (unsigned short *)aligned_addr;
72 }
73
74 while (len--)
75 *p++ = val;
76
77 return dst;
78#endif /* not PREFER_SIZE_OVER_SPEED */
79}
diff --git a/firmware/common/memset16_a.S b/firmware/common/memset16_a.S
new file mode 100755
index 0000000000..9ab1bdcb5b
--- /dev/null
+++ b/firmware/common/memset16_a.S
@@ -0,0 +1,146 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "config.h"
20
21 .section .icode,"ax",@progbits
22
23#ifdef CPU_COLDFIRE
24 .global memset16
25 .type memset16,@function
26
27/* Fills a memory region with specified word value
28 * Start address must be word aligned, length is in words
29 * This version is optimized for speed
30 *
31 * arguments:
32 * (4,%sp) - start address
33 * (8,%sp) - data
34 * (12,%sp) - length
35 *
36 * return value:
37 * %d0 - start address
38 *
39 * register usage:
40 * %d0 - data (spread to both words when using long stores)
41 * %d1 - temporary / data (for burst transfer)
42 * %d2 - data (for burst transfer)
43 * %d3 - data (for burst transfer)
44 * %a0 - start address
45 * %a1 - current address (runs down from end to start)
46 *
47 * For maximum speed this routine uses both long stores and burst mode,
48 * storing whole lines with movem.l. The routine fills memory from end
49 * to start in order to ease returning the start address.
50 */
51memset16:
52 move.l (4,%sp),%a0 /* start address */
53 move.l (8,%sp),%d0 /* data */
54 move.l (12,%sp),%a1 /* length */
55 add.l %a1,%a1
56 add.l %a0,%a1 /* %a1 = end address */
57
58 move.l %a0,%d1
59 addq.l #6,%d1
60 and.l #0xFFFFFFFC,%d1 /* %d1 = first long bound + 4 */
61 cmp.l %d1,%a1 /* at least one aligned longword to fill? */
62 blo.b .no_longs /* no, jump directly to word loop */
63
64 and.l #0xFFFF,%d0 /* start: spread data to both words */
65 move.l %d0,%d1
66 swap %d1
67 or.l %d1,%d0 /* data now in both words */
68
69 move.l %a1,%d1
70 and.l #0xFFFFFFFC,%d1 /* %d1 = last long bound */
71 cmp.l %d1,%a1 /* one extra word? */
72 bls.b .end_w1 /* no: skip */
73
74 move.w %d0,-(%a1) /* set leading word */
75
76.end_w1:
77 moveq.l #30,%d1
78 add.l %a0,%d1
79 and.l #0xFFFFFFF0,%d1 /* %d1 = first line bound + 16 */
80 cmp.l %d1,%a1 /* at least one full line to fill? */
81 blo.b .no_lines /* no, jump to longword loop */
82
83 mov.l %a1,%d1
84 and.l #0xFFFFFFF0,%d1 /* %d1 = last line bound */
85 cmp.l %d1,%a1 /* any longwords to set? */
86 bls.b .end_l1 /* no: skip longword loop */
87
88 /* leading longword loop: sets 0..3 longwords */
89.loop_l1:
90 move.l %d0,-(%a1) /* store longword */
91 cmp.l %d1,%a1 /* runs %a1 down to last line bound */
92 bhi.b .loop_l1
93
94.end_l1:
95 move.l %d2,-(%sp) /* free some registers */
96 move.l %d3,-(%sp)
97
98 move.l %d0,%d1 /* spread data to 4 data registers */
99 move.l %d0,%d2
100 move.l %d0,%d3
101 lea.l (14,%a0),%a0 /* start address += 14, acct. for trl. data */
102
103 /* main loop: set whole lines utilising burst mode */
104.loop_line:
105 lea.l (-16,%a1),%a1 /* pre-decrement */
106 movem.l %d0-%d3,(%a1) /* store line */
107 cmp.l %a0,%a1 /* runs %a1 down to first line bound */
108 bhi.b .loop_line
109
110 lea.l (-14,%a0),%a0 /* correct start address */
111 move.l (%sp)+,%d3 /* restore registers */
112 move.l (%sp)+,%d2
113
114 move.l %a0,%d1 /* %d1 = start address ... */
115 addq.l #2,%d1 /* ... +2, account for possible trailing word */
116 cmp.l %d1,%a1 /* any longwords left */
117 bhi.b .loop_l2 /* yes: jump to longword loop */
118 bra.b .no_longs /* no: skip loop */
119
120.no_lines:
121 move.l %a0,%d1 /* %d1 = start address ... */
122 addq.l #2,%d1 /* ... +2, account for possible trailing word */
123
124 /* trailing longword loop */
125.loop_l2:
126 move.l %d0,-(%a1) /* store longword */
127 cmp.l %d1,%a1 /* runs %a1 down to first long bound */
128 bhi.b .loop_l2
129
130.no_longs:
131 cmp.l %a0,%a1 /* any words left? */
132 bls.b .end_w2 /* no: skip loop */
133
134 /* trailing word loop */
135.loop_w2:
136 move.w %d0,-(%a1) /* store word */
137 cmp.l %a0,%a1 /* runs %a1 down to start address */
138 bhi.b .loop_w2
139
140.end_w2:
141 move.l %a0,%d0 /* return start address */
142 rts
143
144.end:
145 .size memset16,.end-memset16
146#endif
diff --git a/firmware/include/memory.h b/firmware/include/memory.h
new file mode 100755
index 0000000000..2b2a60c7b4
--- /dev/null
+++ b/firmware/include/memory.h
@@ -0,0 +1,27 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Jens Arnold
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _MEMORY_H_
21#define _MEMORY_H_
22
23#include <sys/types.h>
24
25void *memset16(void *dst, int val, size_t len);
26
27#endif /* _MEMORY_H_ */