// File: /workspace/github_c_makefile_star2_O1/erikdubbelboer[P]discnt/src/dict.c
// Function: dictScan
unsigned long dictScan(dict *d,
                       unsigned long v,
                       dictScanFunction *fn,
                       void *privdata)
{
    dictht *t0, *t1;
    const dictEntry *de, *next;
    unsigned long m0, m1;

    if (dictSize(d) == 0) return 0;

    if (!dictIsRehashing(d)) {
        t0 = &(d->ht[0]);
        m0 = t0->sizemask;

        /* Emit entries at cursor */
        de = t0->table[v & m0];
        while (de) {
            next = de->next;
            fn(privdata, de);
            de = next;
        }

    } else {
        t0 = &d->ht[0];
        t1 = &d->ht[1];

        /* Make sure t0 is the smaller and t1 is the bigger table */
        if (t0->size > t1->size) {
            t0 = &d->ht[1];
            t1 = &d->ht[0];
        }

        m0 = t0->sizemask;
        m1 = t1->sizemask;

        /* Emit entries at cursor */
        de = t0->table[v & m0];
        while (de) {
            next = de->next;
            fn(privdata, de);
            de = next;
        }

        /* Iterate over indices in larger table that are the expansion
         * of the index pointed to by the cursor in the smaller table */
        do {
            /* Emit entries at cursor */
            de = t1->table[v & m1];
            while (de) {
                next = de->next;
                fn(privdata, de);
                de = next;
            }

            /* Increment bits not covered by the smaller mask */
            v = (((v | m0) + 1) & ~m0) | (v & m0);

            /* Continue while bits covered by mask difference is non-zero */
        } while (v & (m0 ^ m1));
    }

    /* Set unmasked bits so incrementing the reversed cursor
     * operates on the masked bits of the smaller table */
    v |= ~m0;

    /* Increment the reverse cursor */
    v = rev(v);
    v++;
    v = rev(v);

    return v;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq 0x28(%rdi), %rax
addq 0x48(%rdi), %rax
jne 0x19636
xorl %ebx, %ebx
jmp 0x1979d
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r14
cmpq $-0x1, 0x50(%rdi)
je 0x196fb
leaq 0x10(%rdi), %rax
leaq 0x30(%rdi), %rsi
movq 0x18(%rdi), %rcx
xorl %edx, %edx
cmpq 0x38(%rdi), %rcx
seta %dl
movq %rax, %rcx
cmovaq %rsi, %rcx
cmovaq %rax, %rsi
shll $0x5, %edx
movq 0x10(%rcx), %rbx
movq %rsi, 0x10(%rsp)
movq 0x10(%rsi), %rax
movq %rax, (%rsp)
movq 0x10(%rdi,%rdx), %rax
movq %rbx, %rcx
andq %r14, %rcx
movq (%rax,%rcx,8), %rsi
testq %rsi, %rsi
je 0x196a4
movq 0x10(%rsi), %r13
movq %r15, %rdi
callq *%r12
movq %r13, %rsi
testq %r13, %r13
jne 0x19692
movq %rbx, %rax
notq %rax
movq %rax, 0x8(%rsp)
movq (%rsp), %rbp
xorq %rbx, %rbp
movq 0x10(%rsp), %rax
movq (%rax), %rax
movq %r14, %rcx
andq (%rsp), %rcx
movq (%rax,%rcx,8), %rsi
testq %rsi, %rsi
je 0x196e0
movq 0x10(%rsi), %r13
movq %r15, %rdi
callq *%r12
movq %r13, %rsi
testq %r13, %r13
jne 0x196ce
movq %r14, %rax
orq %rbx, %rax
incq %rax
andq 0x8(%rsp), %rax
andq %rbx, %r14
orq %rax, %r14
testq %rbp, %r14
jne 0x196b6
jmp 0x19724
movq 0x10(%rdi), %rax
movq 0x20(%rdi), %rbx
movq %rbx, %rcx
andq %r14, %rcx
movq (%rax,%rcx,8), %rsi
testq %rsi, %rsi
je 0x19724
movq 0x10(%rsi), %r13
movq %r15, %rdi
callq *%r12
movq %r13, %rsi
testq %r13, %r13
jne 0x19712
notq %rbx
orq %r14, %rbx
movl $0x40, %edx
movq $-0x1, %rax
movl $0x40, %ecx
shrq %rcx
movq %rax, %rsi
shlq %cl, %rsi
movq %rbx, %rdi
shrq %cl, %rbx
shlq %cl, %rdi
xorq %rsi, %rax
xorq %rdi, %rbx
andq %rax, %rbx
xorq %rdi, %rbx
cmpq $0x3, %rdx
movq %rcx, %rdx
ja 0x1973b
incq %rbx
movl $0x40, %edx
movq $-0x1, %rax
movl $0x40, %ecx
shrq %rcx
movq %rax, %rsi
shlq %cl, %rsi
xorq %rsi, %rax
movq %rbx, %rsi
shrq %cl, %rsi
shlq %cl, %rbx
xorq %rbx, %rsi
andq %rax, %rsi
xorq %rsi, %rbx
cmpq $0x3, %rdx
movq %rcx, %rdx
ja 0x19776
movq %rbx, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq