1typedef __SIZE_TYPE__ size_t;
2static int mymemcmp1 (unsigned long int, unsigned long int)
3  __attribute__ ((__nothrow__));
4
5__inline static int
6mymemcmp1 (unsigned long int a, unsigned long int b)
7{
8  long int srcp1 = (long int) &a;
9  long int srcp2 = (long int) &b;
10  unsigned long int a0, b0;
11  do
12    {
13      a0 = ((unsigned char *) srcp1)[0];
14      b0 = ((unsigned char *) srcp2)[0];
15      srcp1 += 1;
16      srcp2 += 1;
17    }
18  while (a0 == b0);
19  return a0 - b0;
20}
21
22static int mymemcmp2 (long, long, size_t) __attribute__ ((__nothrow__));
23
24static int
25mymemcmp2 (long int srcp1, long int srcp2, size_t len)
26{
27  unsigned long int a0, a1;
28  unsigned long int b0, b1;
29  switch (len % 4)
30    {
31    default:
32    case 2:
33      a0 = ((unsigned long int *) srcp1)[0];
34      b0 = ((unsigned long int *) srcp2)[0];
35      srcp1 -= 2 * (sizeof (unsigned long int));
36      srcp2 -= 2 * (sizeof (unsigned long int));
37      len += 2;
38      goto do1;
39    case 3:
40      a1 = ((unsigned long int *) srcp1)[0];
41      b1 = ((unsigned long int *) srcp2)[0];
42      srcp1 -= (sizeof (unsigned long int));
43      srcp2 -= (sizeof (unsigned long int));
44      len += 1;
45      goto do2;
46    case 0:
47      if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
48        return 0;
49      a0 = ((unsigned long int *) srcp1)[0];
50      b0 = ((unsigned long int *) srcp2)[0];
51      goto do3;
52    case 1:
53      a1 = ((unsigned long int *) srcp1)[0];
54      b1 = ((unsigned long int *) srcp2)[0];
55      srcp1 += (sizeof (unsigned long int));
56      srcp2 += (sizeof (unsigned long int));
57      len -= 1;
58      if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
59        goto do0;
60    }
61  do
62    {
63      a0 = ((unsigned long int *) srcp1)[0];
64      b0 = ((unsigned long int *) srcp2)[0];
65      if (a1 != b1)
66        return mymemcmp1 ((a1), (b1));
67    do3:
68      a1 = ((unsigned long int *) srcp1)[1];
69      b1 = ((unsigned long int *) srcp2)[1];
70      if (a0 != b0)
71        return mymemcmp1 ((a0), (b0));
72    do2:
73      a0 = ((unsigned long int *) srcp1)[2];
74      b0 = ((unsigned long int *) srcp2)[2];
75      if (a1 != b1)
76        return mymemcmp1 ((a1), (b1));
77    do1:
78      a1 = ((unsigned long int *) srcp1)[3];
79      b1 = ((unsigned long int *) srcp2)[3];
80      if (a0 != b0)
81        return mymemcmp1 ((a0), (b0));
82      srcp1 += 4 * (sizeof (unsigned long int));
83      srcp2 += 4 * (sizeof (unsigned long int));
84      len -= 4;
85    }
86  while (len != 0);
87do0:
88  if (a1 != b1)
89    return mymemcmp1 ((a1), (b1));
90  return 0;
91}
92
93static int mymemcmp3 (long, long, size_t) __attribute__ ((__nothrow__));
94
95static int
96mymemcmp3 (long int srcp1, long int srcp2, size_t len)
97{
98  unsigned long int a0, a1, a2, a3;
99  unsigned long int b0, b1, b2, b3;
100  unsigned long int x;
101  int shl, shr;
102  shl = 8 * (srcp1 % (sizeof (unsigned long int)));
103  shr = 8 * (sizeof (unsigned long int)) - shl;
104  srcp1 &= -(sizeof (unsigned long int));
105  switch (len % 4)
106    {
107    default:
108    case 2:
109      a1 = ((unsigned long int *) srcp1)[0];
110      a2 = ((unsigned long int *) srcp1)[1];
111      b2 = ((unsigned long int *) srcp2)[0];
112      srcp1 -= 1 * (sizeof (unsigned long int));
113      srcp2 -= 2 * (sizeof (unsigned long int));
114      len += 2;
115      goto do1;
116    case 3:
117      a0 = ((unsigned long int *) srcp1)[0];
118      a1 = ((unsigned long int *) srcp1)[1];
119      b1 = ((unsigned long int *) srcp2)[0];
120      srcp2 -= 1 * (sizeof (unsigned long int));
121      len += 1;
122      goto do2;
123    case 0:
124      if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
125        return 0;
126      a3 = ((unsigned long int *) srcp1)[0];
127      a0 = ((unsigned long int *) srcp1)[1];
128      b0 = ((unsigned long int *) srcp2)[0];
129      srcp1 += 1 * (sizeof (unsigned long int));
130      goto do3;
131    case 1:
132      a2 = ((unsigned long int *) srcp1)[0];
133      a3 = ((unsigned long int *) srcp1)[1];
134      b3 = ((unsigned long int *) srcp2)[0];
135      srcp1 += 2 * (sizeof (unsigned long int));
136      srcp2 += 1 * (sizeof (unsigned long int));
137      len -= 1;
138      if (16 <= 3 * (sizeof (unsigned long int)) && len == 0)
139        goto do0;
140    }
141  do
142    {
143      a0 = ((unsigned long int *) srcp1)[0];
144      b0 = ((unsigned long int *) srcp2)[0];
145      x = (((a2) >> (shl)) | ((a3) << (shr)));
146      if (x != b3)
147        return mymemcmp1 ((x), (b3));
148    do3:
149      a1 = ((unsigned long int *) srcp1)[1];
150      b1 = ((unsigned long int *) srcp2)[1];
151      x = (((a3) >> (shl)) | ((a0) << (shr)));
152      if (x != b0)
153        return mymemcmp1 ((x), (b0));
154    do2:
155      a2 = ((unsigned long int *) srcp1)[2];
156      b2 = ((unsigned long int *) srcp2)[2];
157      x = (((a0) >> (shl)) | ((a1) << (shr)));
158      if (x != b1)
159        return mymemcmp1 ((x), (b1));
160    do1:
161      a3 = ((unsigned long int *) srcp1)[3];
162      b3 = ((unsigned long int *) srcp2)[3];
163      x = (((a1) >> (shl)) | ((a2) << (shr)));
164      if (x != b2)
165        return mymemcmp1 ((x), (b2));
166      srcp1 += 4 * (sizeof (unsigned long int));
167      srcp2 += 4 * (sizeof (unsigned long int));
168      len -= 4;
169    }
170  while (len != 0);
171do0:
172  x = (((a2) >> (shl)) | ((a3) << (shr)));
173  if (x != b3)
174    return mymemcmp1 ((x), (b3));
175  return 0;
176}
177
178__attribute__ ((noinline))
179int mymemcmp (const void *s1, const void *s2, size_t len)
180{
181  unsigned long int a0;
182  unsigned long int b0;
183  long int srcp1 = (long int) s1;
184  long int srcp2 = (long int) s2;
185  if (srcp1 % (sizeof (unsigned long int)) == 0)
186    return mymemcmp2 (srcp1, srcp2, len / (sizeof (unsigned long int)));
187  else
188    return mymemcmp3 (srcp1, srcp2, len / (sizeof (unsigned long int)));
189}
190
191char buf[256];
192
193int
194main (void)
195{
196  char *p;
197  union { long int l; char c[sizeof (long int)]; } u;
198
199  /* The test above assumes little endian and long being the same size
200     as pointer.  */
201  if (sizeof (long int) != sizeof (void *) || sizeof (long int) < 4)
202    return 0;
203  u.l = 0x12345678L;
204  if (u.c[0] != 0x78 || u.c[1] != 0x56 || u.c[2] != 0x34 || u.c[3] != 0x12)
205    return 0;
206
207  p = buf + 16 - (((long int) buf) & 15);
208  __builtin_memcpy (p + 9,
209"\x1\x37\x82\xa7\x55\x49\x9d\xbf\xf8\x44\xb6\x55\x17\x8e\xf9", 15);
210  __builtin_memcpy (p + 128 + 24,
211"\x1\x37\x82\xa7\x55\x49\xd0\xf3\xb7\x2a\x6d\x23\x71\x49\x6a", 15);
212  if (mymemcmp (p + 9, p + 128 + 24, 33) != -51)
213    __builtin_abort ();
214  return 0;
215}
216