Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / movebytes.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
4  * The behaviour and appearence of the program code below can differ to a major
5  * extent from the version distributed by the original author(s).
6  *
7  * For details, see Changelog file distributed with the cdrkit package. If you
8  * received this file from another source then ask the distributing person for
9  * a log of modifications.
10  *
11  */
12
13 /* @(#)movebytes.c      1.13 03/06/15 Copyright 1985, 1989, 1995-2003 J. Schilling */
14 /*
15  *      move data
16  *
17  *      Copyright (c) 1985, 1989, 1995-2003 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <standard.h>
35 #include <align.h>
36 #include <schily.h>
37
38 #define DO8(a)  a; a; a; a; a; a; a; a;
39
40 EXPORT char *
41 movebytes(fromv, tov, cnt)
42         const void      *fromv;
43         void            *tov;
44         int             cnt;
45 {
46         register const char     *from   = fromv;
47         register char           *to     = tov;
48         register int            n;
49
50         /*
51          * If we change cnt to be unsigned, check for == instead of <=
52          */
53         if ((n = cnt) <= 0)
54                 return (to);
55
56         if (from >= to) {
57                 /*
58                  * source is on higher adresses than destination:
59                  *      move bytes forwards
60                  */
61                 if (n >= (int)(8 * sizeof (long))) {
62                         if (l2aligned(from, to)) {
63                                 register const long *froml = (const long *)from;
64                                 register long *tol = (long *)to;
65                                 register int rem = n % (8 * sizeof (long));
66
67                                 n /= (8 * sizeof (long));
68                                 do {
69                                         DO8 (*tol++ = *froml++);
70                                 } while (--n > 0);
71
72                                 from = (const char *)froml;
73                                 to = (char *)tol;
74                                 n = rem;
75                         }
76
77                         if (n >= 8) {
78                                 n -= 8;
79                                 do {
80                                         DO8 (*to++ = *from++);
81                                 } while ((n -= 8) >= 0);
82                                 n += 8;
83                         }
84
85                         if (n > 0) do {
86                                 *to++ = *from++;
87                         } while (--n > 0);
88                         return (to);
89                 }
90                 if (n > 0) do {
91                         *to++ = *from++;
92                 } while (--n > 0);
93                 return (to);
94         } else {
95                 char *ep;
96
97                 /*
98                  * source is on lower adresses than destination:
99                  *      move bytes backwards
100                  */
101                 to += n;
102                 from += n;
103                 ep = to;
104                 if (n >= (int)(8 * sizeof (long))) {
105                         if (l2aligned(from, to)) {
106                                 register const long *froml = (const long *)from;
107                                 register long *tol = (long *)to;
108                                 register int rem = n % (8 * sizeof (long));
109
110                                 n /= (8 * sizeof (long));
111                                 do {
112                                         DO8 (*--tol = *--froml);
113                                 } while (--n > 0);
114
115                                 from = (const char *)froml;
116                                 to = (char *)tol;
117                                 n = rem;
118                         }
119                         if (n >= 8) {
120                                 n -= 8;
121                                 do {
122                                         DO8 (*--to = *--from);
123                                 } while ((n -= 8) >= 0);
124                                 n += 8;
125                         }
126                         if (n > 0) do {
127                                 *--to = *--from;
128                         } while (--n > 0);
129                         return (ep);
130                 }
131                 if (n > 0) do {
132                         *--to = *--from;
133                 } while (--n > 0);
134                 return (ep);
135         }
136 }