~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/alpha/lib/memcpy.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/alpha/lib/memcpy.c (Version linux-6.11.5) and /arch/m68k/lib/memcpy.c (Version linux-6.2.16)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                                  1 /*
  3  *  linux/arch/alpha/lib/memcpy.c              !!   2  * This file is subject to the terms and conditions of the GNU General Public
  4  *                                             !!   3  * License.  See the file COPYING in the main directory of this archive
  5  *  Copyright (C) 1995  Linus Torvalds         !!   4  * for more details.
  6  */                                                 5  */
  7                                                     6 
  8 /*                                             !!   7 #include <linux/module.h>
  9  * This is a reasonably optimized memcpy() rou << 
 10  */                                            << 
 11                                                << 
 12 /*                                             << 
 13  * Note that the C code is written to be optim << 
 14  * at this point gcc is unable to sanely compi << 
 15  * explicit compare against 0 (instead of just << 
 16  * "bge reg, xx"). I hope alpha-gcc will be fi << 
 17  */                                            << 
 18                                                << 
 19 #include <linux/types.h>                       << 
 20 #include <linux/export.h>                      << 
 21 #include <linux/string.h>                           8 #include <linux/string.h>
 22                                                     9 
 23 /*                                             !!  10 void *memcpy(void *to, const void *from, size_t n)
 24  * This should be done in one go with ldq_u*2/ << 
 25  * with a macro so that we can fix it up later << 
 26  */                                            << 
 27 #define ALIGN_DEST_TO8_UP(d,s,n) \             << 
 28         while (d & 7) { \                      << 
 29                 if (n <= 0) return; \          << 
 30                 n--; \                         << 
 31                 *(char *) d = *(char *) s; \   << 
 32                 d++; s++; \                    << 
 33         }                                      << 
 34 #define ALIGN_DEST_TO8_DN(d,s,n) \             << 
 35         while (d & 7) { \                      << 
 36                 if (n <= 0) return; \          << 
 37                 n--; \                         << 
 38                 d--; s--; \                    << 
 39                 *(char *) d = *(char *) s; \   << 
 40         }                                      << 
 41                                                << 
 42 /*                                             << 
 43  * This should similarly be done with ldq_u*2/ << 
 44  * is aligned, but we don't fill in a full qua << 
 45  */                                            << 
 46 #define DO_REST_UP(d,s,n) \                    << 
 47         while (n > 0) { \                      << 
 48                 n--; \                         << 
 49                 *(char *) d = *(char *) s; \   << 
 50                 d++; s++; \                    << 
 51         }                                      << 
 52 #define DO_REST_DN(d,s,n) \                    << 
 53         while (n > 0) { \                      << 
 54                 n--; \                         << 
 55                 d--; s--; \                    << 
 56                 *(char *) d = *(char *) s; \   << 
 57         }                                      << 
 58                                                << 
 59 /*                                             << 
 60  * This should be done with ldq/mask/stq. The  << 
 61  * aligned, but we don't fill in a full quad-w << 
 62  */                                            << 
 63 #define DO_REST_ALIGNED_UP(d,s,n) DO_REST_UP(d << 
 64 #define DO_REST_ALIGNED_DN(d,s,n) DO_REST_DN(d << 
 65                                                << 
 66 /*                                             << 
 67  * This does unaligned memory copies. We want  << 
 68  * an unaligned address, as that would do a re << 
 69  * We also want to avoid double-reading the un << 
 70  *                                             << 
 71  * Note the ordering to try to avoid load (and << 
 72  */                                            << 
 73 static inline void __memcpy_unaligned_up (unsi << 
 74                                           long << 
 75 {                                              << 
 76         ALIGN_DEST_TO8_UP(d,s,n);              << 
 77         n -= 8;                 /* to avoid co << 
 78         if (n >= 0) {                          << 
 79                 unsigned long low_word, high_w << 
 80                 __asm__("ldq_u %0,%1":"=r" (lo << 
 81                 do {                           << 
 82                         unsigned long tmp;     << 
 83                         __asm__("ldq_u %0,%1": << 
 84                         n -= 8;                << 
 85                         __asm__("extql %1,%2,% << 
 86                                 :"=r" (low_wor << 
 87                                 :"r" (low_word << 
 88                         __asm__("extqh %1,%2,% << 
 89                                 :"=r" (tmp)    << 
 90                                 :"r" (high_wor << 
 91                         s += 8;                << 
 92                         *(unsigned long *) d = << 
 93                         d += 8;                << 
 94                         low_word = high_word;  << 
 95                 } while (n >= 0);              << 
 96         }                                      << 
 97         n += 8;                                << 
 98         DO_REST_UP(d,s,n);                     << 
 99 }                                              << 
100                                                << 
101 static inline void __memcpy_unaligned_dn (unsi << 
102                                           long << 
103 {                                                  11 {
104         /* I don't understand AXP assembler we !!  12         void *xto = to;
105         s += n;                                !!  13         size_t temp;
106         d += n;                                << 
107         while (n--)                            << 
108                 * (char *) --d = * (char *) -- << 
109 }                                              << 
110                                                    14 
111 /*                                             !!  15         if (!n)
112  * Hmm.. Strange. The __asm__ here is there to !!  16                 return xto;
113  * for the load-store. I don't know why, but i !!  17         if ((long)to & 1) {
114  * point register for the move seems to slow t !!  18                 char *cto = to;
115  * though).                                    !!  19                 const char *cfrom = from;
116  *                                             !!  20                 *cto++ = *cfrom++;
117  * Note the ordering to try to avoid load (and !!  21                 to = cto;
118  */                                            !!  22                 from = cfrom;
119 static inline void __memcpy_aligned_up (unsign !!  23                 n--;
120                                         long n !!  24         }
121 {                                              !!  25 #if defined(CONFIG_M68000)
122         ALIGN_DEST_TO8_UP(d,s,n);              !!  26         if ((long)from & 1) {
123         n -= 8;                                !!  27                 char *cto = to;
124         while (n >= 0) {                       !!  28                 const char *cfrom = from;
125                 unsigned long tmp;             !!  29                 for (; n; n--)
126                 __asm__("ldq %0,%1":"=r" (tmp) !!  30                         *cto++ = *cfrom++;
127                 n -= 8;                        !!  31                 return xto;
128                 s += 8;                        !!  32         }
129                 *(unsigned long *) d = tmp;    !!  33 #endif
130                 d += 8;                        !!  34         if (n > 2 && (long)to & 2) {
131         }                                      !!  35                 short *sto = to;
132         n += 8;                                !!  36                 const short *sfrom = from;
133         DO_REST_ALIGNED_UP(d,s,n);             !!  37                 *sto++ = *sfrom++;
134 }                                              !!  38                 to = sto;
135 static inline void __memcpy_aligned_dn (unsign !!  39                 from = sfrom;
136                                         long n !!  40                 n -= 2;
137 {                                              !!  41         }
138         s += n;                                !!  42         temp = n >> 2;
139         d += n;                                !!  43         if (temp) {
140         ALIGN_DEST_TO8_DN(d,s,n);              !!  44                 long *lto = to;
141         n -= 8;                                !!  45                 const long *lfrom = from;
142         while (n >= 0) {                       !!  46 #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
143                 unsigned long tmp;             !!  47                 for (; temp; temp--)
144                 s -= 8;                        !!  48                         *lto++ = *lfrom++;
145                 __asm__("ldq %0,%1":"=r" (tmp) !!  49 #else
146                 n -= 8;                        !!  50                 size_t temp1;
147                 d -= 8;                        !!  51                 asm volatile (
148                 *(unsigned long *) d = tmp;    !!  52                         "       movel %2,%3\n"
149         }                                      !!  53                         "       andw  #7,%3\n"
150         n += 8;                                !!  54                         "       lsrl  #3,%2\n"
151         DO_REST_ALIGNED_DN(d,s,n);             !!  55                         "       negw  %3\n"
152 }                                              !!  56                         "       jmp   %%pc@(1f,%3:w:2)\n"
153                                                !!  57                         "4:     movel %0@+,%1@+\n"
154 #undef memcpy                                  !!  58                         "       movel %0@+,%1@+\n"
155                                                !!  59                         "       movel %0@+,%1@+\n"
156 void * memcpy(void * dest, const void *src, si !!  60                         "       movel %0@+,%1@+\n"
157 {                                              !!  61                         "       movel %0@+,%1@+\n"
158         if (!(((unsigned long) dest ^ (unsigne !!  62                         "       movel %0@+,%1@+\n"
159                 __memcpy_aligned_up ((unsigned !!  63                         "       movel %0@+,%1@+\n"
160                                      n);       !!  64                         "       movel %0@+,%1@+\n"
161                 return dest;                   !!  65                         "1:     dbra  %2,4b\n"
                                                   >>  66                         "       clrw  %2\n"
                                                   >>  67                         "       subql #1,%2\n"
                                                   >>  68                         "       jpl   4b"
                                                   >>  69                         : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
                                                   >>  70                         : "" (lfrom), "1" (lto), "2" (temp));
                                                   >>  71 #endif
                                                   >>  72                 to = lto;
                                                   >>  73                 from = lfrom;
                                                   >>  74         }
                                                   >>  75         if (n & 2) {
                                                   >>  76                 short *sto = to;
                                                   >>  77                 const short *sfrom = from;
                                                   >>  78                 *sto++ = *sfrom++;
                                                   >>  79                 to = sto;
                                                   >>  80                 from = sfrom;
                                                   >>  81         }
                                                   >>  82         if (n & 1) {
                                                   >>  83                 char *cto = to;
                                                   >>  84                 const char *cfrom = from;
                                                   >>  85                 *cto = *cfrom;
162         }                                          86         }
163         __memcpy_unaligned_up ((unsigned long) !!  87         return xto;
164         return dest;                           << 
165 }                                                  88 }
166 EXPORT_SYMBOL(memcpy);                             89 EXPORT_SYMBOL(memcpy);
167                                                    90 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php