os-workshop

same materials and sample source for RV32 OS projects
git clone http://frotz.net/git/os-workshop.git
Log | Files | Refs

memmove.c (2028B)


      1 /*
      2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
      3 ** Distributed under the terms of the NewOS License.
      4 */
      5 /*
      6  * Copyright (c) 2008 Travis Geiselbrecht
      7  *
      8  * Use of this source code is governed by a MIT-style
      9  * license that can be found in the LICENSE file or at
     10  * https://opensource.org/licenses/MIT
     11  */
     12 #include <string.h>
     13 #include <stdint.h>
     14 
     15 #if !_ASM_MEMMOVE
     16 
     17 typedef long word;
     18 
     19 #define lsize sizeof(word)
     20 #define lmask (lsize - 1)
     21 
     22 void *
     23 memmove(void *dest, void const *src, size_t count) {
     24     char *d = (char *)dest;
     25     const char *s = (const char *)src;
     26     int len;
     27 
     28     if (count == 0 || dest == src)
     29         return dest;
     30 
     31     if ((long)d < (long)s) {
     32         if (((long)d | (long)s) & lmask) {
     33             // src and/or dest do not align on word boundary
     34             if ((((long)d ^ (long)s) & lmask) || (count < lsize))
     35                 len = count; // copy the rest of the buffer with the byte mover
     36             else
     37                 len = lsize - ((long)d & lmask); // move the ptrs up to a word boundary
     38 
     39             count -= len;
     40             for (; len > 0; len--)
     41                 *d++ = *s++;
     42         }
     43         for (len = count / lsize; len > 0; len--) {
     44             *(word *)d = *(word *)s;
     45             d += lsize;
     46             s += lsize;
     47         }
     48         for (len = count & lmask; len > 0; len--)
     49             *d++ = *s++;
     50     } else {
     51         d += count;
     52         s += count;
     53         if (((long)d | (long)s) & lmask) {
     54             // src and/or dest do not align on word boundary
     55             if ((((long)d ^ (long)s) & lmask) || (count <= lsize))
     56                 len = count;
     57             else
     58                 len = ((long)d & lmask);
     59 
     60             count -= len;
     61             for (; len > 0; len--)
     62                 *--d = *--s;
     63         }
     64         for (len = count / lsize; len > 0; len--) {
     65             d -= lsize;
     66             s -= lsize;
     67             *(word *)d = *(word *)s;
     68         }
     69         for (len = count & lmask; len > 0; len--)
     70             *--d = *--s;
     71     }
     72 
     73     return dest;
     74 }
     75 
     76 #endif
     77