// File: /workspace/github_c_makefile_star2_O3/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 %r14
pushq %rbx
subq $0x50, %rsp
movq %rcx, %rax
pcmpeqd %xmm0, %xmm0
movdqu %xmm0, 0x1c(%rsp)
movdqa %xmm0, 0x10(%rsp)
movzbl 0xf0(%rdi), %r11d
movl %r11d, 0x10(%rsp)
movzbl 0xf1(%rdi), %r10d
movl %r10d, 0x1c(%rsp)
pxor %xmm0, %xmm0
movdqa %xmm0, 0x30(%rsp)
movdqa %xmm0, 0x40(%rsp)
movl $0x1, %r9d
movl %r9d, 0x30(%rsp,%r11,4)
movl $0x2, 0x30(%rsp,%r10,4)
movb 0x505(%rsi), %cl
decb %cl
shll %cl, %r9d
movl 0x4e8(%rsi), %ecx
leal -0x1(%r9), %esi
xorl %ebx, %ebx
movl $0x0, %ebp
testl %ecx, %ecx
je 0x7579
movzbl 0x34(%rdi), %ebp
movzbl 0x490(%rdx,%rbx), %r14d
subl %ebp, %r14d
movl %r14d, %ebp
andl %esi, %ebp
andl %r9d, %r14d
subl %r14d, %ebp
addl %r9d, %ebp
movb %bpl, 0x8(%rsp,%rbx)
incq %rbx
cmpq $0x8, %rbx
jne 0x7555
movzbl 0x8(%rsp,%r11), %ecx
cmpl %ecx, %r9d
jbe 0x76e1
movzbl 0x8(%rsp,%r10), %ecx
cmpl %ecx, %r9d
jbe 0x76e1
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %ecx, %ecx
xorl %edx, %edx
cmpl $0x0, 0x30(%rsp,%rcx,4)
jne 0x75d7
movzbl 0x8(%rsp,%rcx), %esi
cmpl %esi, %r9d
ja 0x75d7
testl %eax, %eax
setns %r8b
cmpl %esi, %edx
seta %r10b
testb %r10b, %r8b
jne 0x75d7
movl %ecx, %eax
movl %esi, %edx
incq %rcx
cmpq $0x8, %rcx
jne 0x75b1
testl %eax, %eax
js 0x75f2
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 0x7621
movzbl 0x8(%rsp,%rcx), %esi
cmpl %esi, %r9d
ja 0x7621
testl %eax, %eax
sets %r8b
cmpl %esi, %edx
seta %r10b
orb %r8b, %r10b
je 0x7621
movl %ecx, %eax
movl %esi, %edx
incq %rcx
cmpq $0x8, %rcx
jne 0x75fb
testl %eax, %eax
js 0x763c
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 0x766b
movzbl 0x8(%rsp,%rdx), %esi
cmpl %esi, %r9d
ja 0x766b
testl %ecx, %ecx
sets %r8b
cmpl %esi, %eax
seta %r10b
orb %r8b, %r10b
je 0x766b
movl %edx, %ecx
movl %esi, %eax
incq %rdx
cmpq $0x8, %rdx
jne 0x7645
testl %ecx, %ecx
js 0x767c
movl %ecx, 0x24(%rsp)
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 0x76a1
movl %esi, %edx
movl %eax, %r8d
incq %rcx
movl %r8d, %eax
movl %edx, %esi
cmpq $0x8, %rcx
jne 0x7683
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 0x76b1
xorl %eax, %eax
xorl %ecx, %ecx
movb 0x10(%rsp,%rcx,4), %dl
movb %dl, 0xf2(%rdi,%rcx)
incq %rcx
cmpq $0x7, %rcx
jne 0x76cb
jmp 0x76fa
leaq 0xe38(%rip), %rdx       # 0x8520
movq %rax, %rdi
movq %r8, %rsi
xorl %eax, %eax
callq 0x1030
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x50, %rsp
popq %rbx
popq %r14
popq %rbp
retq