source: trunk/libs/newlib/src/newlib/libc/machine/riscv/memcpy.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 1.8 KB
Line 
1/* Copyright (c) 2017  SiFive Inc. All rights reserved.
2
3   This copyrighted material is made available to anyone wishing to use,
4   modify, copy, or redistribute it subject to the terms and conditions
5   of the FreeBSD License.   This program is distributed in the hope that
6   it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
7   including the implied warranties of MERCHANTABILITY or FITNESS FOR
8   A PARTICULAR PURPOSE.  A copy of this license is available at
9   http://www.opensource.org/licenses.
10*/
11
12#include <string.h>
13#include <stdint.h>
14
15#define unlikely(X) __builtin_expect (!!(X), 0)
16
17void *
18memcpy(void *__restrict aa, const void *__restrict bb, size_t n)
19{
20  #define BODY(a, b, t) { \
21    t tt = *b; \
22    a++, b++; \
23    *(a - 1) = tt; \
24  }
25
26  char *a = (char *)aa;
27  const char *b = (const char *)bb;
28  char *end = a + n;
29  uintptr_t msk = sizeof (long) - 1;
30  if (unlikely ((((uintptr_t)a & msk) != ((uintptr_t)b & msk))
31               || n < sizeof (long)))
32    {
33small:
34      if (__builtin_expect (a < end, 1))
35        while (a < end)
36          BODY (a, b, char);
37      return aa;
38    }
39
40  if (unlikely (((uintptr_t)a & msk) != 0))
41    while ((uintptr_t)a & msk)
42      BODY (a, b, char);
43
44  long *la = (long *)a;
45  const long *lb = (const long *)b;
46  long *lend = (long *)((uintptr_t)end & ~msk);
47
48  if (unlikely (la < (lend - 8)))
49    {
50      while (la < (lend - 8))
51        {
52          long b0 = *lb++;
53          long b1 = *lb++;
54          long b2 = *lb++;
55          long b3 = *lb++;
56          long b4 = *lb++;
57          long b5 = *lb++;
58          long b6 = *lb++;
59          long b7 = *lb++;
60          long b8 = *lb++;
61          *la++ = b0;
62          *la++ = b1;
63          *la++ = b2;
64          *la++ = b3;
65          *la++ = b4;
66          *la++ = b5;
67          *la++ = b6;
68          *la++ = b7;
69          *la++ = b8;
70        }
71    }
72
73  while (la < lend)
74    BODY (la, lb, long);
75
76  a = (char *)la;
77  b = (const char *)lb;
78  if (unlikely (a < end))
79    goto small;
80  return aa;
81}
Note: See TracBrowser for help on using the repository browser.