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 * A copy of the CDDL is also available via the Internet at
15 * http://www.opensource.org/licenses/cddl1.txt
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file CDDL.Schily.txt from this distribution.
19 */
20
21 #include <schily/standard.h>
22 #include <schily/align.h>
23 #include <schily/types.h>
24 #include <schily/schily.h>
25
26 #define DO8(a) a; a; a; a; a; a; a; a;
27
28 /*
29 * movebytes(from, to, cnt) is the same as memmove(to, from, cnt)
30 */
31 EXPORT char *
movebytes(fromv,tov,cnt)32 movebytes(fromv, tov, cnt)
33 const void *fromv;
34 void *tov;
35 ssize_t cnt;
36 {
37 register const char *from = fromv;
38 register char *to = tov;
39 register ssize_t n;
40
41 /*
42 * If we change cnt to be unsigned, check for == instead of <=
43 */
44 if ((n = cnt) <= 0)
45 return (to);
46
47 if (from >= to) {
48 /*
49 * source is on higher addresses than destination:
50 * move bytes forwards
51 */
52 if (n >= (ssize_t)(8 * sizeof (long))) {
53 if (l2aligned(from, to)) {
54 register const long *froml = (const long *)from;
55 register long *tol = (long *)to;
56 register ssize_t rem = n % (8 * sizeof (long));
57
58 n /= (8 * sizeof (long));
59 do {
60 DO8 (*tol++ = *froml++);
61 } while (--n > 0);
62
63 from = (const char *)froml;
64 to = (char *)tol;
65 n = rem;
66 }
67
68 if (n >= 8) {
69 n -= 8;
70 do {
71 DO8 (*to++ = *from++);
72 } while ((n -= 8) >= 0);
73 n += 8;
74 }
75
76 if (n > 0) do {
77 *to++ = *from++;
78 } while (--n > 0);
79 return (to);
80 }
81 if (n > 0) do {
82 *to++ = *from++;
83 } while (--n > 0);
84 return (to);
85 } else {
86 char *ep;
87
88 /*
89 * source is on lower addresses than destination:
90 * move bytes backwards
91 */
92 to += n;
93 from += n;
94 ep = to;
95 if (n >= (ssize_t)(8 * sizeof (long))) {
96 if (l2aligned(from, to)) {
97 register const long *froml = (const long *)from;
98 register long *tol = (long *)to;
99 register ssize_t rem = n % (8 * sizeof (long));
100
101 n /= (8 * sizeof (long));
102 do {
103 DO8 (*--tol = *--froml);
104 } while (--n > 0);
105
106 from = (const char *)froml;
107 to = (char *)tol;
108 n = rem;
109 }
110 if (n >= 8) {
111 n -= 8;
112 do {
113 DO8 (*--to = *--from);
114 } while ((n -= 8) >= 0);
115 n += 8;
116 }
117 if (n > 0) do {
118 *--to = *--from;
119 } while (--n > 0);
120 return (ep);
121 }
122 if (n > 0) do {
123 *--to = *--from;
124 } while (--n > 0);
125 return (ep);
126 }
127 }
128