3 <<memcpy>>---copy memory regions, optimized for the mips processors
7 void* memcpy(void *<[out]>, const void *<[in]>, size_t <[n]>);
10 void *memcpy(<[out]>, <[in]>, <[n]>
16 This function copies <[n]> bytes from the memory region
17 pointed to by <[in]> to the memory region pointed to by
20 If the regions overlap, the behavior is undefined.
23 <<memcpy>> returns a pointer to the first byte of the <[out]>
29 <<memcpy>> requires no supporting OS subroutines.
40 #define wordtype long long
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)
59 _DEFUN (memcpy
, (dst0
, src0
, len0
),
64 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) || defined(__mips16)
65 char *dst
= (char *) dst0
;
66 char *src
= (char *) src0
;
78 _CONST
char *src
= src0
;
79 wordtype
*aligned_dst
;
80 _CONST wordtype
*aligned_src
;
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. */
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
;
109 /* Copy one long or long long word at a time if possible. */
110 iter
= len
/ LITTLEBLOCKSIZE
;
111 len
= len
% LITTLEBLOCKSIZE
;
115 *aligned_dst
++ = *aligned_src
++;
119 /* Pick up any residual with a byte copier. */
120 dst
= (char*)aligned_dst
;
121 src
= (char*)aligned_src
;
132 /* Handle unaligned moves here, using lwr/lwl and swr/swl where possible */
135 #ifndef NO_UNALIGNED_LOADSTORE
137 int *int_src
= (int *)src
;
138 int *int_dst
= (int *)dst
;
143 __asm__ ("ulw %0,%1" : "=r" (tmp
) : "m" (*int_src
));
146 __asm__ ("usw %1,%0" : "=m" (*int_dst
) : "r" (tmp
));
150 /* Pick up any residual with a byte copier. */
151 dst
= (char*)int_dst
;
152 src
= (char*)int_src
;
163 #endif /* not PREFER_SIZE_OVER_SPEED */