~ [ 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-2.6.0)


  1 // SPDX-License-Identifier: GPL-2.0            << 
  2 /*                                             << 
  3  *  linux/arch/alpha/lib/memcpy.c              << 
  4  *                                             << 
  5  *  Copyright (C) 1995  Linus Torvalds         << 
  6  */                                            << 
  7                                                << 
  8 /*                                             << 
  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>                            1 #include <linux/types.h>
 20 #include <linux/export.h>                      << 
 21 #include <linux/string.h>                      << 
 22                                                << 
 23 /*                                             << 
 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                                                     2 
 59 /*                                             !!   3 void * memcpy(void * to, const void * from, size_t n)
 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 {                                                   4 {
 76         ALIGN_DEST_TO8_UP(d,s,n);              !!   5   void *xto = to;
 77         n -= 8;                 /* to avoid co !!   6   size_t temp, temp1;
 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                                                     7 
101 static inline void __memcpy_unaligned_dn (unsi !!   8   if (!n)
102                                           long !!   9     return xto;
103 {                                              !!  10   if ((long) to & 1)
104         /* I don't understand AXP assembler we !!  11     {
105         s += n;                                !!  12       char *cto = to;
106         d += n;                                !!  13       const char *cfrom = from;
107         while (n--)                            !!  14       *cto++ = *cfrom++;
108                 * (char *) --d = * (char *) -- !!  15       to = cto;
109 }                                              !!  16       from = cfrom;
110                                                !!  17       n--;
111 /*                                             !!  18     }
112  * Hmm.. Strange. The __asm__ here is there to !!  19   if (n > 2 && (long) to & 2)
113  * for the load-store. I don't know why, but i !!  20     {
114  * point register for the move seems to slow t !!  21       short *sto = to;
115  * though).                                    !!  22       const short *sfrom = from;
116  *                                             !!  23       *sto++ = *sfrom++;
117  * Note the ordering to try to avoid load (and !!  24       to = sto;
118  */                                            !!  25       from = sfrom;
119 static inline void __memcpy_aligned_up (unsign !!  26       n -= 2;
120                                         long n !!  27     }
121 {                                              !!  28   temp = n >> 2;
122         ALIGN_DEST_TO8_UP(d,s,n);              !!  29   if (temp)
123         n -= 8;                                !!  30     {
124         while (n >= 0) {                       !!  31       long *lto = to;
125                 unsigned long tmp;             !!  32       const long *lfrom = from;
126                 __asm__("ldq %0,%1":"=r" (tmp) !!  33 
127                 n -= 8;                        !!  34       __asm__ __volatile__("movel %2,%3\n\t"
128                 s += 8;                        !!  35                            "andw  #7,%3\n\t"
129                 *(unsigned long *) d = tmp;    !!  36                            "lsrl  #3,%2\n\t"
130                 d += 8;                        !!  37                            "negw  %3\n\t"
131         }                                      !!  38                            "jmp   %%pc@(1f,%3:w:2)\n\t"
132         n += 8;                                !!  39                            "4:\t"
133         DO_REST_ALIGNED_UP(d,s,n);             !!  40                            "movel %0@+,%1@+\n\t"
134 }                                              !!  41                            "movel %0@+,%1@+\n\t"
135 static inline void __memcpy_aligned_dn (unsign !!  42                            "movel %0@+,%1@+\n\t"
136                                         long n !!  43                            "movel %0@+,%1@+\n\t"
137 {                                              !!  44                            "movel %0@+,%1@+\n\t"
138         s += n;                                !!  45                            "movel %0@+,%1@+\n\t"
139         d += n;                                !!  46                            "movel %0@+,%1@+\n\t"
140         ALIGN_DEST_TO8_DN(d,s,n);              !!  47                            "movel %0@+,%1@+\n\t"
141         n -= 8;                                !!  48                            "1:\t"
142         while (n >= 0) {                       !!  49                            "dbra  %2,4b\n\t"
143                 unsigned long tmp;             !!  50                            "clrw  %2\n\t"
144                 s -= 8;                        !!  51                            "subql #1,%2\n\t"
145                 __asm__("ldq %0,%1":"=r" (tmp) !!  52                            "jpl   4b\n\t"
146                 n -= 8;                        !!  53                            : "=a" (lfrom), "=a" (lto), "=d" (temp),
147                 d -= 8;                        !!  54                            "=&d" (temp1)
148                 *(unsigned long *) d = tmp;    !!  55                            : "" (lfrom), "1" (lto), "2" (temp)
149         }                                      !!  56                            );
150         n += 8;                                !!  57       to = lto;
151         DO_REST_ALIGNED_DN(d,s,n);             !!  58       from = lfrom;
152 }                                              !!  59     }
153                                                !!  60   if (n & 2)
154 #undef memcpy                                  !!  61     {
155                                                !!  62       short *sto = to;
156 void * memcpy(void * dest, const void *src, si !!  63       const short *sfrom = from;
157 {                                              !!  64       *sto++ = *sfrom++;
158         if (!(((unsigned long) dest ^ (unsigne !!  65       to = sto;
159                 __memcpy_aligned_up ((unsigned !!  66       from = sfrom;
160                                      n);       !!  67     }
161                 return dest;                   !!  68   if (n & 1)
162         }                                      !!  69     {
163         __memcpy_unaligned_up ((unsigned long) !!  70       char *cto = to;
164         return dest;                           !!  71       const char *cfrom = from;
                                                   >>  72       *cto = *cfrom;
                                                   >>  73     }
                                                   >>  74   return xto;
165 }                                                  75 }
166 EXPORT_SYMBOL(memcpy);                         << 
167                                                    76 

~ [ 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