// File: /workspace/github_c_makefile_star2_O1/dwbuiten[P]obuparse/obuparse.c
// Function: obp_set_frame_refs
static inline int _obp_set_frame_refs(OBPFrameHeader *fh, OBPSequenceHeader *seq, OBPState *state, OBPError *err)
{
    int usedFrame[8];
    uint32_t curFrameHint, lastOrderHint, goldOrderHint, latestOrderHint, earliestOrderHint;
    int32_t ref;
    uint8_t shiftedOrderHints[8];
    const int Ref_Frame_List[7 - 2] = { 2, 3, 5, 6, 7 }; /*LAST2_FRAME, LAST3_FRAME, BWDREF_FRAME, ALTREF2_FRAME, ALTREF_FRAME */
    int32_t ref_frame_idx[8];

    for (int i = 0; i < 7; i++) {
        ref_frame_idx[i] = -1;
    }
    ref_frame_idx[1 - 1] = fh->last_frame_idx;
    ref_frame_idx[4 - 1] = fh->gold_frame_idx;
    for (int i = 0; i < 8; i++) {
        usedFrame[i] = 0;
    }
    usedFrame[fh->last_frame_idx] = 1;
    usedFrame[fh->gold_frame_idx] = 2;
    curFrameHint                  = 1 << (seq->OrderHintBits - 1);
    for (int i = 0; i < 8; i++) {
        shiftedOrderHints[i] = curFrameHint + _obp_get_relative_dist(state->RefOrderHint[i], fh->order_hint, seq);
    }
    lastOrderHint = shiftedOrderHints[fh->last_frame_idx];
    goldOrderHint = shiftedOrderHints[fh->gold_frame_idx];
    if (lastOrderHint >= curFrameHint || goldOrderHint >= curFrameHint) {
        snprintf(err->error, err->size, "(lastOrderHint >= curFrameHint || goldOrderHint >= curFrameHint) not allowed.");
        return -1;
    }
    /* find_latest_backward() */
    ref             = -1;
    latestOrderHint = 0;
    for (int i = 0; i < 8; i++) {
        uint32_t hint = shiftedOrderHints[i];
        if (!usedFrame[i] && (hint >= curFrameHint) && (ref < 0 || hint >= latestOrderHint)) {
            ref             = i;
            latestOrderHint = hint;
        }
    }
    if (ref >= 0) {
        ref_frame_idx[7 - 1] = ref;
        usedFrame[ref]       = 1;
    }
    /* find_earliest_backward() */
    ref               = -1;
    earliestOrderHint = 0;
    for (int i = 0; i < 8; i++) {
        uint32_t hint = shiftedOrderHints[i];
        if (!usedFrame[i] && (hint >= curFrameHint) && (ref < 0 || hint < earliestOrderHint)) {
            ref               = i;
            earliestOrderHint = hint;
        }
    }
    if (ref >= 0) {
        ref_frame_idx[5 - 1] = ref;
        usedFrame[ref]       = 1;
    }
    /* find_earliest_backward() */
    ref               = -1;
    earliestOrderHint = 0;
    for (int i = 0; i < 8; i++) {
        uint32_t hint = shiftedOrderHints[i];
        if (!usedFrame[i] && (hint >= curFrameHint) && (ref < 0 || hint < earliestOrderHint)) {
            ref               = i;
            earliestOrderHint = hint;
        }
    }
    if (ref >= 0) {
        ref_frame_idx[6 - 1] = ref;
        usedFrame[ref]       = 1;
    }
    for (int i = 0; i < 7 - 2; i++) {
        uint8_t refFrame = Ref_Frame_List[i];
        if (ref_frame_idx[refFrame - 1] < 0) {
            int32_t subref              = -1;
            uint32_t subLatestOrderHint = 0;
            for (int i = 0; i < 8; i++) {
                uint32_t hint = shiftedOrderHints[i];
                if (!usedFrame[i] && (hint < curFrameHint) && (ref < 0 || hint >= subLatestOrderHint)) {
                    ref                = i;
                    subLatestOrderHint = 0;
                }
            }
            ref = subref;
            if (ref >= 0) {
                ref_frame_idx[refFrame - 1] = ref;
                usedFrame[ref]              = 1;
            }
        }
    }
    ref = -1;
    for (int i = 0; i < 8; i++) {
        uint32_t hint = shiftedOrderHints[i];
        if (ref < 0 || hint < earliestOrderHint) {
            ref = i;
            earliestOrderHint = hint;
        }
    }
    for (int i = 0; i < 7; i++) {
        if (ref_frame_idx[i] < 0) {
            ref_frame_idx[i] = ref;
        }
    }
    for (int i = 0; i < 7; i++) {
        fh->ref_frame_idx[i] = ref_frame_idx[i];
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x58, %rsp
movq %rcx, %rax
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x1c(%rsp)
movdqa %xmm0, 0x10(%rsp)
movzbl 0xf0(%rdi), %r10d
movl %r10d, 0x10(%rsp)
movzbl 0xf1(%rdi), %r9d
movl %r9d, 0x1c(%rsp)
pxor %xmm0, %xmm0
movdqa %xmm0, 0x30(%rsp)
movdqa %xmm0, 0x40(%rsp)
movl $0x1, %r8d
movl %r8d, 0x30(%rsp,%r10,4)
movl $0x2, 0x30(%rsp,%r9,4)
movb 0x505(%rsi), %cl
decb %cl
shll %cl, %r8d
movl 0x4e8(%rsi), %ecx
leal -0x1(%r8), %esi
xorl %r11d, %r11d
movl $0x0, %ebx
testl %ecx, %ecx
je 0x9ba3
movzbl 0x34(%rdi), %ebx
movzbl 0x490(%rdx,%r11), %ebp
subl %ebx, %ebp
movl %ebp, %ebx
andl %esi, %ebx
andl %r8d, %ebp
subl %ebp, %ebx
addl %r8d, %ebx
movb %bl, 0x8(%rsp,%r11)
incq %r11
cmpq $0x8, %r11
jne 0x9b82
movzbl 0x8(%rsp,%r10), %ecx
cmpl %ecx, %r8d
jbe 0x9d15
movzbl 0x8(%rsp,%r9), %ecx
cmpl %ecx, %r8d
jbe 0x9d15
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
xorl %edx, %edx
cmpl $0x0, 0x30(%rsp,%rcx,4)
jne 0x9c01
movzbl 0x8(%rsp,%rcx), %esi
cmpl %esi, %r8d
ja 0x9c01
testl %eax, %eax
setns %r9b
cmpl %esi, %edx
seta %r10b
testb %r10b, %r9b
jne 0x9c01
movl %ecx, %eax
movl %esi, %edx
incq %rcx
cmpq $0x8, %rcx
jne 0x9bdb
testl %eax, %eax
js 0x9c1c
movl %eax, 0x28(%rsp)
movl %eax, %eax
movl $0x1, 0x30(%rsp,%rax,4)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
xorl %edx, %edx
cmpl $0x0, 0x30(%rsp,%rcx,4)
jne 0x9c4b
movzbl 0x8(%rsp,%rcx), %esi
cmpl %esi, %r8d
ja 0x9c4b
testl %eax, %eax
sets %r9b
cmpl %esi, %edx
seta %r10b
orb %r9b, %r10b
je 0x9c4b
movl %ecx, %eax
movl %esi, %edx
incq %rcx
cmpq $0x8, %rcx
jne 0x9c25
testl %eax, %eax
js 0x9c66
movl %eax, 0x20(%rsp)
movl %eax, %eax
movl $0x1, 0x30(%rsp,%rax,4)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %edx, %edx
xorl %eax, %eax
cmpl $0x0, 0x30(%rsp,%rdx,4)
jne 0x9c95
movzbl 0x8(%rsp,%rdx), %esi
cmpl %esi, %r8d
ja 0x9c95
testl %ecx, %ecx
sets %r9b
cmpl %esi, %eax
seta %r10b
orb %r9b, %r10b
je 0x9c95
movl %edx, %ecx
movl %esi, %eax
incq %rdx
cmpq $0x8, %rdx
jne 0x9c6f
testl %ecx, %ecx
js 0x9cb0
movl %ecx, 0x24(%rsp)
movl %ecx, %ecx
movl $0x1, 0x30(%rsp,%rcx,4)
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
movzbl 0x8(%rsp,%rcx), %r8d
testl %esi, %esi
sets %dl
cmpl %r8d, %eax
seta %r9b
orb %dl, %r9b
movl %ecx, %edx
jne 0x9cd5
movl %esi, %edx
movl %eax, %r8d
incq %rcx
movl %r8d, %eax
movl %edx, %esi
cmpq $0x8, %rcx
jne 0x9cb7
xorl %eax, %eax
movl 0x10(%rsp,%rax,4), %ecx
testl %ecx, %ecx
cmovsl %edx, %ecx
movl %ecx, 0x10(%rsp,%rax,4)
incq %rax
cmpq $0x7, %rax
jne 0x9ce5
xorl %eax, %eax
xorl %ecx, %ecx
movb 0x10(%rsp,%rcx,4), %dl
movb %dl, 0xf2(%rdi,%rcx)
incq %rcx
cmpq $0x7, %rcx
jne 0x9cff
jmp 0x9d2f
movq (%rax), %rdi
movq 0x8(%rax), %rsi
leaq 0x17c1(%rip), %rdx      # 0xb4e4
xorl %eax, %eax
callq 0x1030
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x58, %rsp
popq %rbx
popq %rbp
retq