summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES12
-rw-r--r--firmware/common/memcpy.c117
-rw-r--r--firmware/common/memcpy_a.S (renamed from firmware/common/memcpy.S)0
-rw-r--r--firmware/common/memset.c109
-rw-r--r--firmware/common/memset_a.S (renamed from firmware/common/memset.S)0
5 files changed, 233 insertions, 5 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index e6c007c1d0..e08d986ec1 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1,6 +1,3 @@
1#ifdef ARCHOS_GMINI120
2common/string.c
3#endif
4#ifdef IRIVER_H100 1#ifdef IRIVER_H100
5crt0.S 2crt0.S
6backlight.c 3backlight.c
@@ -30,6 +27,13 @@ common/strncpy.c
30common/strrchr.c 27common/strrchr.c
31common/strtok.c 28common/strtok.c
32common/timefuncs.c 29common/timefuncs.c
30#if (CONFIG_CPU == SH7034) || (CONFIG_CPU == MCF5249)
31common/memcpy_a.S
32common/memset_a.S
33#else
34common/memcpy.c
35common/memset.c
36#endif
33debug.c 37debug.c
34drivers/adc.c 38drivers/adc.c
35#ifdef HAVE_MMC 39#ifdef HAVE_MMC
@@ -81,8 +85,6 @@ system.c
81thread.c 85thread.c
82usb.c 86usb.c
83bitswap.S 87bitswap.S
84common/memcpy.S
85common/memset.S
86crt0.S 88crt0.S
87descramble.S 89descramble.S
88drivers/lcd.S 90drivers/lcd.S
diff --git a/firmware/common/memcpy.c b/firmware/common/memcpy.c
new file mode 100644
index 0000000000..49678920fa
--- /dev/null
+++ b/firmware/common/memcpy.c
@@ -0,0 +1,117 @@
1/*
2FUNCTION
3 <<memcpy>>---copy memory regions
4
5ANSI_SYNOPSIS
6 #include <string.h>
7 void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
8
9TRAD_SYNOPSIS
10 void *memcpy(<[out]>, <[in]>, <[n]>
11 void *<[out]>;
12 void *<[in]>;
13 size_t <[n]>;
14
15DESCRIPTION
16 This function copies <[n]> bytes from the memory region
17 pointed to by <[in]> to the memory region pointed to by
18 <[out]>.
19
20 If the regions overlap, the behavior is undefined.
21
22RETURNS
23 <<memcpy>> returns a pointer to the first byte of the <[out]>
24 region.
25
26PORTABILITY
27<<memcpy>> is ANSI C.
28
29<<memcpy>> requires no supporting OS subroutines.
30
31QUICKREF
32 memcpy ansi pure
33 */
34
35#include <_ansi.h>
36#include <stddef.h>
37#include <limits.h>
38
39/* Nonzero if either X or Y is not aligned on a "long" boundary. */
40#define UNALIGNED(X, Y) \
41 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
42
43/* How many bytes are copied each iteration of the 4X unrolled loop. */
44#define BIGBLOCKSIZE (sizeof (long) << 2)
45
46/* How many bytes are copied each iteration of the word copy loop. */
47#define LITTLEBLOCKSIZE (sizeof (long))
48
49/* Threshhold for punting to the byte copier. */
50#define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
51
52_PTR
53_DEFUN (memcpy, (dst0, src0, len0),
54 _PTR dst0 _AND
55 _CONST _PTR src0 _AND
56 size_t len0) __attribute__ ((section (".icode")));
57
58_PTR
59_DEFUN (memcpy, (dst0, src0, len0),
60 _PTR dst0 _AND
61 _CONST _PTR src0 _AND
62 size_t len0)
63{
64#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
65 char *dst = (char *) dst0;
66 char *src = (char *) src0;
67
68 _PTR save = dst0;
69
70 while (len0--)
71 {
72 *dst++ = *src++;
73 }
74
75 return save;
76#else
77 char *dst = dst0;
78 _CONST char *src = src0;
79 long *aligned_dst;
80 _CONST long *aligned_src;
81 unsigned int len = len0;
82
83 /* If the size is small, or either SRC or DST is unaligned,
84 then punt into the byte copy loop. This should be rare. */
85 if (!TOO_SMALL(len) && !UNALIGNED (src, dst))
86 {
87 aligned_dst = (long*)dst;
88 aligned_src = (long*)src;
89
90 /* Copy 4X long words at a time if possible. */
91 while (len >= BIGBLOCKSIZE)
92 {
93 *aligned_dst++ = *aligned_src++;
94 *aligned_dst++ = *aligned_src++;
95 *aligned_dst++ = *aligned_src++;
96 *aligned_dst++ = *aligned_src++;
97 len -= BIGBLOCKSIZE;
98 }
99
100 /* Copy one long word at a time if possible. */
101 while (len >= LITTLEBLOCKSIZE)
102 {
103 *aligned_dst++ = *aligned_src++;
104 len -= LITTLEBLOCKSIZE;
105 }
106
107 /* Pick up any residual with a byte copier. */
108 dst = (char*)aligned_dst;
109 src = (char*)aligned_src;
110 }
111
112 while (len--)
113 *dst++ = *src++;
114
115 return dst0;
116#endif /* not PREFER_SIZE_OVER_SPEED */
117}
diff --git a/firmware/common/memcpy.S b/firmware/common/memcpy_a.S
index e129b99442..e129b99442 100644
--- a/firmware/common/memcpy.S
+++ b/firmware/common/memcpy_a.S
diff --git a/firmware/common/memset.c b/firmware/common/memset.c
new file mode 100644
index 0000000000..c370191cda
--- /dev/null
+++ b/firmware/common/memset.c
@@ -0,0 +1,109 @@
1/*
2FUNCTION
3 <<memset>>---set an area of memory
4
5INDEX
6 memset
7
8ANSI_SYNOPSIS
9 #include <string.h>
10 void *memset(const void *<[dst]>, int <[c]>, size_t <[length]>);
11
12TRAD_SYNOPSIS
13 #include <string.h>
14 void *memset(<[dst]>, <[c]>, <[length]>)
15 void *<[dst]>;
16 int <[c]>;
17 size_t <[length]>;
18
19DESCRIPTION
20 This function converts the argument <[c]> into an unsigned
21 char and fills the first <[length]> characters of the array
22 pointed to by <[dst]> to the value.
23
24RETURNS
25 <<memset>> returns the value of <[m]>.
26
27PORTABILITY
28<<memset>> is ANSI C.
29
30 <<memset>> requires no supporting OS subroutines.
31
32QUICKREF
33 memset ansi pure
34*/
35
36#include <string.h>
37
38#define LBLOCKSIZE (sizeof(long))
39#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
40#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
41
42_PTR
43_DEFUN (memset, (m, c, n),
44 _PTR m _AND
45 int c _AND
46 size_t n)
47{
48#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
49 char *s = (char *) m;
50
51 while (n-- != 0)
52 {
53 *s++ = (char) c;
54 }
55
56 return m;
57#else
58 char *s = (char *) m;
59 unsigned int i;
60 unsigned long buffer;
61 unsigned long *aligned_addr;
62
63 if (!TOO_SMALL (n) && !UNALIGNED (m))
64 {
65 /* If we get this far, we know that n is large and m is word-aligned. */
66
67 aligned_addr = (unsigned long*)m;
68
69 /* Store C into each char sized location in BUFFER so that
70 we can set large blocks quickly. */
71 c &= 0xff;
72 if (LBLOCKSIZE == 4)
73 {
74 buffer = (c << 8) | c;
75 buffer |= (buffer << 16);
76 }
77 else
78 {
79 buffer = 0;
80 for (i = 0; i < LBLOCKSIZE; i++)
81 buffer = (buffer << 8) | c;
82 }
83
84 while (n >= LBLOCKSIZE*4)
85 {
86 *aligned_addr++ = buffer;
87 *aligned_addr++ = buffer;
88 *aligned_addr++ = buffer;
89 *aligned_addr++ = buffer;
90 n -= 4*LBLOCKSIZE;
91 }
92
93 while (n >= LBLOCKSIZE)
94 {
95 *aligned_addr++ = buffer;
96 n -= LBLOCKSIZE;
97 }
98 /* Pick up the remainder with a bytewise loop. */
99 s = (char*)aligned_addr;
100 }
101
102 while (n--)
103 {
104 *s++ = (char)c;
105 }
106
107 return m;
108#endif /* not PREFER_SIZE_OVER_SPEED */
109}
diff --git a/firmware/common/memset.S b/firmware/common/memset_a.S
index bce8936089..bce8936089 100644
--- a/firmware/common/memset.S
+++ b/firmware/common/memset_a.S