1 /* @(#)movebytes.c 1.18 09/10/17 Copyright 1985, 1989, 1995-2009 J. Schilling */ 2 /* 3 * move data 4 * 5 * Copyright (c) 1985, 1989, 1995-2009 J. Schilling 6 */ 7 /* 8 * The contents of this file are subject to the terms of the 9 * Common Development and Distribution License, Version 1.0 only 10 * (the "License"). You may not use this file except in compliance 11 * with the License. 12 * 13 * See the file CDDL.Schily.txt in this distribution for details. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file CDDL.Schily.txt from this distribution. 17 */ 18 19 #include <schily/standard.h> 20 #include <schily/align.h> 21 #include <schily/types.h> 22 #include <schily/schily.h> 23 24 #define DO8(a) a; a; a; a; a; a; a; a; 25 26 /* 27 * movebytes(from, to, cnt) is the same as memmove(to, from, cnt) 28 */ 29 EXPORT char * 30 movebytes(fromv, tov, cnt) 31 const void *fromv; 32 void *tov; 33 ssize_t cnt; 34 { 35 register const char *from = fromv; 36 register char *to = tov; 37 register ssize_t n; 38 39 /* 40 * If we change cnt to be unsigned, check for == instead of <= 41 */ 42 if ((n = cnt) <= 0) 43 return (to); 44 45 if (from >= to) { 46 /* 47 * source is on higher addresses than destination: 48 * move bytes forwards 49 */ 50 if (n >= (ssize_t)(8 * sizeof (long))) { 51 if (l2aligned(from, to)) { 52 register const long *froml = (const long *)from; 53 register long *tol = (long *)to; 54 register ssize_t rem = n % (8 * sizeof (long)); 55 56 n /= (8 * sizeof (long)); 57 do { 58 DO8 (*tol++ = *froml++); 59 } while (--n > 0); 60 61 from = (const char *)froml; 62 to = (char *)tol; 63 n = rem; 64 } 65 66 if (n >= 8) { 67 n -= 8; 68 do { 69 DO8 (*to++ = *from++); 70 } while ((n -= 8) >= 0); 71 n += 8; 72 } 73 74 if (n > 0) do { 75 *to++ = *from++; 76 } while (--n > 0); 77 return (to); 78 } 79 if (n > 0) do { 80 *to++ = *from++; 81 } while (--n > 0); 82 return (to); 83 } else { 84 char *ep; 85 86 /* 87 * source is on lower addresses than destination: 88 * move bytes backwards 89 */ 90 to += n; 91 from += n; 92 ep = to; 93 if (n >= (ssize_t)(8 * sizeof (long))) { 94 if (l2aligned(from, to)) { 95 register const long *froml = (const long *)from; 96 register long *tol = (long *)to; 97 register ssize_t rem = n % (8 * sizeof (long)); 98 99 n /= (8 * sizeof (long)); 100 do { 101 DO8 (*--tol = *--froml); 102 } while (--n > 0); 103 104 from = (const char *)froml; 105 to = (char *)tol; 106 n = rem; 107 } 108 if (n >= 8) { 109 n -= 8; 110 do { 111 DO8 (*--to = *--from); 112 } while ((n -= 8) >= 0); 113 n += 8; 114 } 115 if (n > 0) do { 116 *--to = *--from; 117 } while (--n > 0); 118 return (ep); 119 } 120 if (n > 0) do { 121 *--to = *--from; 122 } while (--n > 0); 123 return (ep); 124 } 125 } 126