Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / librols / cmpbytes.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 /* @(#)cmpbytes.c       1.15 03/06/15 Copyright 1988, 1995-2003 J. Schilling */
14 /*
15  *      compare data
16  *
17  *      Copyright (c) 1988, 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 int
41 cmpbytes(fromp, top, cnt)
42         const void      *fromp;
43         const void      *top;
44         int             cnt;
45 {
46         register const char     *from   = (char *)fromp;
47         register const char     *to     = (char *)top;
48         register int            n;
49         register int            i;
50
51         /*
52          * If we change cnt to be unsigned, check for == instead of <=
53          */
54         if ((n = cnt) <= 0)
55                 return (cnt);
56
57         /*
58          * Compare byte-wise until properly aligned for a long pointer.
59          */
60         i = sizeof (long) - 1;
61         while (--n >= 0 && --i >= 0 && !l2aligned(from, to)) {
62                 if (*to++ != *from++)
63                         goto cdiff;
64         }
65         n++;
66
67         if (n >= (int)(8 * sizeof (long))) {
68                 if (l2aligned(from, to)) {
69                         register const long *froml = (const long *)from;
70                         register const long *tol   = (const long *)to;
71                         register int rem = n % (8 * sizeof (long));
72
73                         n /= (8 * sizeof (long));
74                         do {
75                                 DO8(
76                                         if (*tol++ != *froml++)
77                                                 break;
78                                 );
79                         } while (--n > 0);
80
81                         if (n > 0) {
82                                 --froml;
83                                 --tol;
84                                 to = (const char *)tol;
85                                 from = (const char *)froml;
86                                 goto ldiff;
87                         }
88                         to = (const char *)tol;
89                         from = (const char *)froml;
90                         n = rem;
91                 }
92
93                 if (n >= 8) {
94                         n -= 8;
95                         do {
96                                 DO8(
97                                         if (*to++ != *from++)
98                                                 goto cdiff;
99                                 );
100                         } while ((n -= 8) >= 0);
101                         n += 8;
102                 }
103                 if (n > 0) do {
104                         if (*to++ != *from++)
105                                 goto cdiff;
106                 } while (--n > 0);
107                 return (cnt);
108         }
109         if (n > 0) do {
110                 if (*to++ != *from++)
111                         goto cdiff;
112         } while (--n > 0);
113         return (cnt);
114 ldiff:
115         n = sizeof (long);
116         do {
117                 if (*to++ != *from++)
118                         goto cdiff;
119         } while (--n > 0);
120 cdiff:
121         return (--from - (char *)fromp);
122 }