typedef __SIZE_TYPE__ size_t; static int mymemcmp1 (unsigned long int, unsigned long int) __attribute__ ((__nothrow__)); __inline static int mymemcmp1 (unsigned long int a, unsigned long int b) { long int srcp1 = (long int) &a; long int srcp2 = (long int) &b; unsigned long int a0, b0; do { a0 = ((unsigned char *) srcp1)[0]; b0 = ((unsigned char *) srcp2)[0]; srcp1 += 1; srcp2 += 1; } while (a0 == b0); return a0 - b0; } static int mymemcmp2 (long, long, size_t) __attribute__ ((__nothrow__)); static int mymemcmp2 (long int srcp1, long int srcp2, size_t len) { unsigned long int a0, a1; unsigned long int b0, b1; switch (len % 4) { default: case 2: a0 = ((unsigned long int *) srcp1)[0]; b0 = ((unsigned long int *) srcp2)[0]; srcp1 -= 2 * (sizeof (unsigned long int)); srcp2 -= 2 * (sizeof (unsigned long int)); len += 2; goto do1; case 3: a1 = ((unsigned long int *) srcp1)[0]; b1 = ((unsigned long int *) srcp2)[0]; srcp1 -= (sizeof (unsigned long int)); srcp2 -= (sizeof (unsigned long int)); len += 1; goto do2; case 0: if (16 <= 3 * (sizeof (unsigned long int)) && len == 0) return 0; a0 = ((unsigned long int *) srcp1)[0]; b0 = ((unsigned long int *) srcp2)[0]; goto do3; case 1: a1 = ((unsigned long int *) srcp1)[0]; b1 = ((unsigned long int *) srcp2)[0]; srcp1 += (sizeof (unsigned long int)); srcp2 += (sizeof (unsigned long int)); len -= 1; if (16 <= 3 * (sizeof (unsigned long int)) && len == 0) goto do0; } do { a0 = ((unsigned long int *) srcp1)[0]; b0 = ((unsigned long int *) srcp2)[0]; if (a1 != b1) return mymemcmp1 ((a1), (b1)); do3: a1 = ((unsigned long int *) srcp1)[1]; b1 = ((unsigned long int *) srcp2)[1]; if (a0 != b0) return mymemcmp1 ((a0), (b0)); do2: a0 = ((unsigned long int *) srcp1)[2]; b0 = ((unsigned long int *) srcp2)[2]; if (a1 != b1) return mymemcmp1 ((a1), (b1)); do1: a1 = ((unsigned long int *) srcp1)[3]; b1 = ((unsigned long int *) srcp2)[3]; if (a0 != b0) return mymemcmp1 ((a0), (b0)); srcp1 += 4 * (sizeof (unsigned long int)); srcp2 += 4 * (sizeof (unsigned long int)); len -= 4; } while (len != 0); do0: if (a1 != b1) return mymemcmp1 ((a1), (b1)); return 0; } static int mymemcmp3 (long, long, size_t) __attribute__ ((__nothrow__)); static int mymemcmp3 (long int srcp1, long int srcp2, size_t len) { unsigned long int a0, a1, a2, a3; unsigned long int b0, b1, b2, b3; unsigned long int x; int shl, shr; shl = 8 * (srcp1 % (sizeof (unsigned long int))); shr = 8 * (sizeof (unsigned long int)) - shl; srcp1 &= -(sizeof (unsigned long int)); switch (len % 4) { default: case 2: a1 = ((unsigned long int *) srcp1)[0]; a2 = ((unsigned long int *) srcp1)[1]; b2 = ((unsigned long int *) srcp2)[0]; srcp1 -= 1 * (sizeof (unsigned long int)); srcp2 -= 2 * (sizeof (unsigned long int)); len += 2; goto do1; case 3: a0 = ((unsigned long int *) srcp1)[0]; a1 = ((unsigned long int *) srcp1)[1]; b1 = ((unsigned long int *) srcp2)[0]; srcp2 -= 1 * (sizeof (unsigned long int)); len += 1; goto do2; case 0: if (16 <= 3 * (sizeof (unsigned long int)) && len == 0) return 0; a3 = ((unsigned long int *) srcp1)[0]; a0 = ((unsigned long int *) srcp1)[1]; b0 = ((unsigned long int *) srcp2)[0]; srcp1 += 1 * (sizeof (unsigned long int)); goto do3; case 1: a2 = ((unsigned long int *) srcp1)[0]; a3 = ((unsigned long int *) srcp1)[1]; b3 = ((unsigned long int *) srcp2)[0]; srcp1 += 2 * (sizeof (unsigned long int)); srcp2 += 1 * (sizeof (unsigned long int)); len -= 1; if (16 <= 3 * (sizeof (unsigned long int)) && len == 0) goto do0; } do { a0 = ((unsigned long int *) srcp1)[0]; b0 = ((unsigned long int *) srcp2)[0]; x = (((a2) >> (shl)) | ((a3) << (shr))); if (x != b3) return mymemcmp1 ((x), (b3)); do3: a1 = ((unsigned long int *) srcp1)[1]; b1 = ((unsigned long int *) srcp2)[1]; x = (((a3) >> (shl)) | ((a0) << (shr))); if (x != b0) return mymemcmp1 ((x), (b0)); do2: a2 = ((unsigned long int *) srcp1)[2]; b2 = ((unsigned long int *) srcp2)[2]; x = (((a0) >> (shl)) | ((a1) << (shr))); if (x != b1) return mymemcmp1 ((x), (b1)); do1: a3 = ((unsigned long int *) srcp1)[3]; b3 = ((unsigned long int *) srcp2)[3]; x = (((a1) >> (shl)) | ((a2) << (shr))); if (x != b2) return mymemcmp1 ((x), (b2)); srcp1 += 4 * (sizeof (unsigned long int)); srcp2 += 4 * (sizeof (unsigned long int)); len -= 4; } while (len != 0); do0: x = (((a2) >> (shl)) | ((a3) << (shr))); if (x != b3) return mymemcmp1 ((x), (b3)); return 0; } __attribute__ ((noinline)) int mymemcmp (const void *s1, const void *s2, size_t len) { unsigned long int a0; unsigned long int b0; long int srcp1 = (long int) s1; long int srcp2 = (long int) s2; if (srcp1 % (sizeof (unsigned long int)) == 0) return mymemcmp2 (srcp1, srcp2, len / (sizeof (unsigned long int))); else return mymemcmp3 (srcp1, srcp2, len / (sizeof (unsigned long int))); } char buf[256]; int main (void) { char *p; union { long int l; char c[sizeof (long int)]; } u; /* The test above assumes little endian and long being the same size as pointer. */ if (sizeof (long int) != sizeof (void *) || sizeof (long int) < 4) return 0; u.l = 0x12345678L; if (u.c[0] != 0x78 || u.c[1] != 0x56 || u.c[2] != 0x34 || u.c[3] != 0x12) return 0; p = buf + 16 - (((long int) buf) & 15); __builtin_memcpy (p + 9, "\x1\x37\x82\xa7\x55\x49\x9d\xbf\xf8\x44\xb6\x55\x17\x8e\xf9", 15); __builtin_memcpy (p + 128 + 24, "\x1\x37\x82\xa7\x55\x49\xd0\xf3\xb7\x2a\x6d\x23\x71\x49\x6a", 15); if (mymemcmp (p + 9, p + 128 + 24, 33) != -51) __builtin_abort (); return 0; }