Cygwin: access: Fix X_OK behaviour for backup operators and admins
[newlib-cygwin.git] / newlib / libc / machine / riscv / memcpy.c
blob4098f3ab1052e05113f445abcbf9d732eeb01e93
1 /* Copyright (c) 2017 SiFive Inc. All rights reserved.
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.
12 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
13 //memcpy defined in memcpy-asm.S
14 #else
16 #include <string.h>
17 #include <stdint.h>
18 #include "../../string/local.h"
20 #define unlikely(X) __builtin_expect (!!(X), 0)
22 void *
23 __inhibit_loop_to_libcall
24 memcpy(void *__restrict aa, const void *__restrict bb, size_t n)
26 #define BODY(a, b, t) { \
27 t tt = *b; \
28 a++, b++; \
29 *(a - 1) = tt; \
32 char *a = (char *)aa;
33 const char *b = (const char *)bb;
34 char *end = a + n;
35 uintptr_t msk = sizeof (long) - 1;
36 if (unlikely ((((uintptr_t)a & msk) != ((uintptr_t)b & msk))
37 || n < sizeof (long)))
39 small:
40 if (__builtin_expect (a < end, 1))
41 while (a < end)
42 BODY (a, b, char);
43 return aa;
46 if (unlikely (((uintptr_t)a & msk) != 0))
47 while ((uintptr_t)a & msk)
48 BODY (a, b, char);
50 long *la = (long *)a;
51 const long *lb = (const long *)b;
52 long *lend = (long *)((uintptr_t)end & ~msk);
54 if (unlikely (lend - la > 8))
56 while (lend - la > 8)
58 long b0 = *lb++;
59 long b1 = *lb++;
60 long b2 = *lb++;
61 long b3 = *lb++;
62 long b4 = *lb++;
63 long b5 = *lb++;
64 long b6 = *lb++;
65 long b7 = *lb++;
66 long b8 = *lb++;
67 *la++ = b0;
68 *la++ = b1;
69 *la++ = b2;
70 *la++ = b3;
71 *la++ = b4;
72 *la++ = b5;
73 *la++ = b6;
74 *la++ = b7;
75 *la++ = b8;
79 while (la < lend)
80 BODY (la, lb, long);
82 a = (char *)la;
83 b = (const char *)lb;
84 if (unlikely (a < end))
85 goto small;
86 return aa;
88 #endif