/* Driver: fixed-bcmp differential vs memcmp (same sweep as diff_harness). */
#include <stdio.h>
#include <string.h>
#include <stdint.h>

int bcmp_fixed(const void *, const void *, size_t);
extern unsigned long g_below_start[2], g_past_end[2], g_in[2],
                     g_max_below[2], g_max_past[2];
extern const unsigned char *g_lo[2], *g_hi[2];
extern int g_case[3];

#define BUF 256
static unsigned char A[BUF], B[BUF];

static uint64_t s_state = 0x9e3779b97f4a7c15ULL;
static uint64_t prng(void)
{
    s_state ^= s_state << 13; s_state ^= s_state >> 7; s_state ^= s_state << 17;
    return s_state;
}

int main(void)
{
    long fails = 0, cases = 0;
    for (size_t n = 0; n <= 96; n++)
        for (int off1 = 0; off1 < 8; off1++)
            for (int off2 = 0; off2 < 8; off2++) {
                for (int i = 0; i < BUF; i++) { A[i] = (unsigned char)(i * 7 + off1); B[i] = A[i]; }
                for (size_t d = 0; d <= n; d++) {
                    if (d < n) B[off2 + d] ^= 0x5a;
                    g_case[0] = off1; g_case[1] = off2; g_case[2] = (int)n;
                    g_lo[0] = A + off1; g_hi[0] = A + off1 + n;
                    g_lo[1] = B + off2; g_hi[1] = B + off2 + n;
                    int r = bcmp_fixed(A + off1, B + off2, n);
                    int m = memcmp(A + off1, B + off2, n);
                    cases++;
                    if ((r == 0) != (m == 0)) { if (++fails < 10)
                        printf("FAIL off1=%d off2=%d n=%zu d=%zu\n", off1, off2, n, d); }
                    if (d < n) B[off2 + d] ^= 0x5a;
                }
            }
    for (long it = 0; it < 2000000; it++) {
        int off1 = (int)(prng() % 32), off2 = (int)(prng() % 32);
        size_t n = (size_t)(prng() % 192);
        for (int i = 0; i < BUF; i++) { unsigned char v = (unsigned char)prng(); A[i] = v; B[i] = v; }
        if (prng() & 1 && n) { size_t dd = (size_t)(prng() % n); if (prng() & 1) A[off1+dd] ^= 1; else B[off2+dd] ^= 1; }
        g_case[0] = off1; g_case[1] = off2; g_case[2] = (int)n;
        g_lo[0] = A + off1; g_hi[0] = A + off1 + n;
        g_lo[1] = B + off2; g_hi[1] = B + off2 + n;
        int r = bcmp_fixed(A + off1, B + off2, n);
        int m = memcmp(A + off1, B + off2, n);
        cases++;
        if ((r == 0) != (m == 0)) fails++;
    }
    printf("fixed diff: %ld cases, %ld failures\n", cases, fails);
    printf("fixed loads: below-start=%lu/%lu past-end=%lu/%lu (max %lu B / %lu B)\n",
           g_below_start[0], g_below_start[1], g_past_end[0], g_past_end[1],
           g_max_below[0] > g_max_below[1] ? g_max_below[0] : g_max_below[1],
           g_max_past[0] > g_max_past[1] ? g_max_past[0] : g_max_past[1]);
    printf("RESULT: %s\n", fails == 0 &&
           g_below_start[0] == 0 && g_below_start[1] == 0 &&
           g_past_end[0] == 0 && g_past_end[1] == 0 ? "FIX-PASS" : "FIX-FAIL");
    return 0;
}
