fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / newlib / libc / machine / mips / memcpy.c
blob761f7e9ab77a19b4a846f983c24c6f978b759a04
1 /*
2 FUNCTION
3 <<memcpy>>---copy memory regions, optimized for the mips processors
5 ANSI_SYNOPSIS
6 #include <string.h>
7 void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
9 TRAD_SYNOPSIS
10 void *memcpy(<[out]>, <[in]>, <[n]>
11 void *<[out]>;
12 void *<[in]>;
13 size_t <[n]>;
15 DESCRIPTION
16 This function copies <[n]> bytes from the memory region
17 pointed to by <[in]> to the memory region pointed to by
18 <[out]>.
20 If the regions overlap, the behavior is undefined.
22 RETURNS
23 <<memcpy>> returns a pointer to the first byte of the <[out]>
24 region.
26 PORTABILITY
27 <<memcpy>> is ANSI C.
29 <<memcpy>> requires no supporting OS subroutines.
31 QUICKREF
32 memcpy ansi pure
35 #include <_ansi.h>
36 #include <stddef.h>
37 #include <limits.h>
39 #ifdef __mips64
40 #define wordtype long long
41 #else
42 #define wordtype long
43 #endif
45 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
46 #define UNALIGNED(X, Y) \
47 (((long)X & (sizeof (wordtype) - 1)) | ((long)Y & (sizeof (wordtype) - 1)))
49 /* How many bytes are copied each iteration of the 4X unrolled loop. */
50 #define BIGBLOCKSIZE (sizeof (wordtype) << 2)
52 /* How many bytes are copied each iteration of the word copy loop. */
53 #define LITTLEBLOCKSIZE (sizeof (wordtype))
55 /* Threshhold for punting to the byte copier. */
56 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
58 _PTR
59 _DEFUN (memcpy, (dst0, src0, len0),
60 _PTR dst0 _AND
61 _CONST _PTR src0 _AND
62 size_t len0)
64 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__mips16)
65 char *dst = (char *) dst0;
66 char *src = (char *) src0;
68 _PTR save = dst0;
70 while (len0--)
72 *dst++ = *src++;
75 return save;
76 #else
77 char *dst = dst0;
78 _CONST char *src = src0;
79 wordtype *aligned_dst;
80 _CONST wordtype *aligned_src;
81 int len = len0;
82 size_t iter;
84 /* Handle aligned moves here. */
85 if (!UNALIGNED (src, dst))
87 iter = len / BIGBLOCKSIZE;
88 len = len % BIGBLOCKSIZE;
89 aligned_dst = (wordtype *)dst;
90 aligned_src = (wordtype *)src;
92 /* Copy 4X long or long long words at a time if possible. */
93 while (iter > 0)
95 wordtype tmp0 = aligned_src[0];
96 wordtype tmp1 = aligned_src[1];
97 wordtype tmp2 = aligned_src[2];
98 wordtype tmp3 = aligned_src[3];
100 aligned_dst[0] = tmp0;
101 aligned_dst[1] = tmp1;
102 aligned_dst[2] = tmp2;
103 aligned_dst[3] = tmp3;
104 aligned_src += 4;
105 aligned_dst += 4;
106 iter--;
109 /* Copy one long or long long word at a time if possible. */
110 iter = len / LITTLEBLOCKSIZE;
111 len = len % LITTLEBLOCKSIZE;
113 while (iter > 0)
115 *aligned_dst++ = *aligned_src++;
116 iter--;
119 /* Pick up any residual with a byte copier. */
120 dst = (char*)aligned_dst;
121 src = (char*)aligned_src;
123 while (len > 0)
125 *dst++ = *src++;
126 len--;
129 return dst0;
132 /* Handle unaligned moves here, using lwr/lwl and swr/swl where possible */
133 else
135 #ifndef NO_UNALIGNED_LOADSTORE
136 int tmp;
137 int *int_src = (int *)src;
138 int *int_dst = (int *)dst;
139 iter = len / 4;
140 len = len % 4;
141 while (iter > 0)
143 __asm__ ("ulw %0,%1" : "=r" (tmp) : "m" (*int_src));
144 iter--;
145 int_src++;
146 __asm__ ("usw %1,%0" : "=m" (*int_dst) : "r" (tmp));
147 int_dst++;
150 /* Pick up any residual with a byte copier. */
151 dst = (char*)int_dst;
152 src = (char*)int_src;
153 #endif
155 while (len > 0)
157 *dst++ = *src++;
158 len--;
161 return dst0;
163 #endif /* not PREFER_SIZE_OVER_SPEED */