^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * License. See the file COPYING in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) void *memcpy(void *to, const void *from, size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) void *xto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) size_t temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return xto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) if ((long)to & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) char *cto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) const char *cfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *cto++ = *cfrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) to = cto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) from = cfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) n--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #if defined(CONFIG_M68000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if ((long)from & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) char *cto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const char *cfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) for (; n; n--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *cto++ = *cfrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return xto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (n > 2 && (long)to & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) short *sto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) const short *sfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *sto++ = *sfrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) to = sto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) from = sfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) n -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) temp = n >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (temp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) long *lto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const long *lfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) for (; temp; temp--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *lto++ = *lfrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) size_t temp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) asm volatile (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) " movel %2,%3\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) " andw #7,%3\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) " lsrl #3,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) " negw %3\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) " jmp %%pc@(1f,%3:w:2)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "4: movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) " movel %0@+,%1@+\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "1: dbra %2,4b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) " clrw %2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) " subql #1,%2\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) " jpl 4b"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) : "0" (lfrom), "1" (lto), "2" (temp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) to = lto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) from = lfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (n & 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) short *sto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) const short *sfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *sto++ = *sfrom++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) to = sto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) from = sfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (n & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) char *cto = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const char *cfrom = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *cto = *cfrom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return xto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) EXPORT_SYMBOL(memcpy);