1 typedef __SIZE_TYPE__ size_t;
2 static int mymemcmp1 (unsigned long int, unsigned long int)
3   __attribute__ ((__nothrow__));
4 
5 __inline static int
mymemcmp1(unsigned long int a,unsigned long int b)6 mymemcmp1 (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 
22 static int mymemcmp2 (long, long, size_t) __attribute__ ((__nothrow__));
23 
24 static int
mymemcmp2(long int srcp1,long int srcp2,size_t len)25 mymemcmp2 (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);
87 do0:
88   if (a1 != b1)
89     return mymemcmp1 ((a1), (b1));
90   return 0;
91 }
92 
93 static int mymemcmp3 (long, long, size_t) __attribute__ ((__nothrow__));
94 
95 static int
mymemcmp3(long int srcp1,long int srcp2,size_t len)96 mymemcmp3 (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);
171 do0:
172   x = (((a2) >> (shl)) | ((a3) << (shr)));
173   if (x != b3)
174     return mymemcmp1 ((x), (b3));
175   return 0;
176 }
177 
178 __attribute__ ((noinline))
mymemcmp(const void * s1,const void * s2,size_t len)179 int 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 
191 char buf[256];
192 
193 int
main(void)194 main (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