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