1// Copyright 2016 The Fuchsia Authors
2// Copyright (c) 2008 Travis Geiselbrecht
3//
4// Use of this source code is governed by a MIT-style
5// license that can be found in the LICENSE file or at
6// https://opensource.org/licenses/MIT
7
8#include <string.h>
9#include <sys/types.h>
10
11
12#if !_ASM_MEMCPY
13
14typedef long word;
15
16#define lsize sizeof(word)
17#define lmask (lsize - 1)
18
19void *memcpy(void *dest, const void *src, size_t count)
20{
21    char *d = (char *)dest;
22    const char *s = (const char *)src;
23    int len;
24
25    if (count == 0 || dest == src)
26        return dest;
27
28    if (((long)d | (long)s) & lmask) {
29        // src and/or dest do not align on word boundary
30        if ((((long)d ^ (long)s) & lmask) || (count < lsize))
31            len = count; // copy the rest of the buffer with the byte mover
32        else
33            len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
34
35        count -= len;
36        for (; len > 0; len--)
37            *d++ = *s++;
38    }
39    for (len = count / lsize; len > 0; len--) {
40        *(word *)d = *(word *)s;
41        d += lsize;
42        s += lsize;
43    }
44    for (len = count & lmask; len > 0; len--)
45        *d++ = *s++;
46
47    return dest;
48}
49
50#endif
51