// File: /workspace/github_cpp_makefile_star2_O1/lukasz-wiecaszek[P]h264iframedecoder/picture_cabac.cpp
// Function: ymn::h264::picture_cabac::intraNxN_pred_mode_cache_init(unsigned int)
void picture_cabac::intraNxN_pred_mode_cache_init(uint32_t constrained_intra_pred_flag)
{
    const mb* curr_mb = m_context_variables.curr_mb;
    const int* left_blocks = m_context_variables.left_blocks;
    mb_cache& ipm_cache = m_context_variables.intraNxN_pred_mode_cache;

    if (curr_mb->top && MB_IS_INTRA_NxN(curr_mb->top->type)) {
        const mb* top = curr_mb->top;

        if (MB_IS_INTRA_4x4(top->type))
        {
            ipm_cache[0 * 8 + 4] = top->intra_luma_pred_mode.m4x4[3 * 4 + 0];
            ipm_cache[0 * 8 + 5] = top->intra_luma_pred_mode.m4x4[3 * 4 + 1];
            ipm_cache[0 * 8 + 6] = top->intra_luma_pred_mode.m4x4[3 * 4 + 2];
            ipm_cache[0 * 8 + 7] = top->intra_luma_pred_mode.m4x4[3 * 4 + 3];
        }
        else
        {
            ipm_cache[0 * 8 + 4] = top->intra_luma_pred_mode.m8x8[2];
            ipm_cache[0 * 8 + 5] = top->intra_luma_pred_mode.m8x8[2];
            ipm_cache[0 * 8 + 6] = top->intra_luma_pred_mode.m8x8[3];
            ipm_cache[0 * 8 + 7] = top->intra_luma_pred_mode.m8x8[3];
        }
    }
    else {
        int pred = MB_INTRA_PRED_LUMA_NxN_DC;

        if (curr_mb->top == nullptr || (MB_IS_INTER(curr_mb->top->type) && constrained_intra_pred_flag))
            pred = -1;

        ipm_cache[0 * 8 + 4] = pred;
        ipm_cache[0 * 8 + 5] = pred;
        ipm_cache[0 * 8 + 6] = pred;
        ipm_cache[0 * 8 + 7] = pred;
    }

    for (int i = 0; i < 2; ++i) {
        if (curr_mb->left_pair[i] && MB_IS_INTRA_NxN(curr_mb->left_pair[i]->type)) {
            const mb* left = curr_mb->left_pair[i];

            if (MB_IS_INTRA_4x4(left->type)) {
                ipm_cache[3 + 1 * 8 + 2 * 8 * i] =
                    left->intra_luma_pred_mode.m4x4[3 + left_blocks[0 + 2 * i] * 4];

                ipm_cache[3 + 2 * 8 + 2 * 8 * i] =
                    left->intra_luma_pred_mode.m4x4[3 + left_blocks[1 + 2 * i] * 4];
            }
            else {
                ipm_cache[3 + 1 * 8 + 2 * 8 * i] =
                    left->intra_luma_pred_mode.m8x8[left_blocks[0 + 2 * i] | 1];

                ipm_cache[3 + 2 * 8 + 2 * 8 * i] =
                    left->intra_luma_pred_mode.m8x8[left_blocks[1 + 2 * i] | 1];
            }
        }
        else {
            int pred = MB_INTRA_PRED_LUMA_NxN_DC;

            if (curr_mb->left_pair[i] == nullptr|| (MB_IS_INTER(curr_mb->left_pair[i]->type) && constrained_intra_pred_flag))
                pred = -1;

            ipm_cache[3 + 1 * 8 + 2 * 8 * i] = pred;
            ipm_cache[3 + 2 * 8 + 2 * 8 * i] = pred;
        }
    }
}

// Assembly:
movq 0x28(%rdi), %rax
movq 0x50(%rax), %rcx
testq %rcx, %rcx
je 0x17032
movl 0x10(%rcx), %edx
andl $0x3, %edx
je 0x1701b
cmpl $0x1, %edx
jne 0x17042
movb 0x64(%rcx), %dl
movb %dl, 0x5c(%rdi)
movb 0x65(%rcx), %dl
movb %dl, 0x5d(%rdi)
movb 0x66(%rcx), %dl
movb %dl, 0x5e(%rdi)
movb 0x67(%rcx), %cl
jmp 0x17057
testq %rcx, %rcx
je 0x17032
movb $0x2, %dl
testl %esi, %esi
je 0x17034
movl $0xf0, %r8d
andl 0x10(%rcx), %r8d
je 0x17034
movb $-0x1, %dl
movzbl %dl, %ecx
imull $0x1010101, %ecx, %ecx  # imm = 0x1010101
movl %ecx, 0x5c(%rdi)
jmp 0x1705a
movb 0x5a(%rcx), %dl
movb %dl, 0x5c(%rdi)
movb 0x5a(%rcx), %dl
movb %dl, 0x5d(%rdi)
movb 0x5b(%rcx), %dl
movb %dl, 0x5e(%rdi)
movb 0x5b(%rcx), %cl
movb %cl, 0x5f(%rdi)
pushq %rbx
movq 0x48(%rdi), %rcx
xorl %edx, %edx
movl $0xf0, %r8d
xorl %r9d, %r9d
movq 0x40(%rax,%r9,8), %r10
testq %r10, %r10
je 0x170ba
movl 0x10(%r10), %r11d
andl $0x3, %r11d
je 0x170a5
cmpl $0x1, %r11d
jne 0x170c7
movslq (%rcx,%r9,8), %r11
movb 0x5b(%r10,%r11,4), %r11b
movq %r9, %rbx
shlq $0x4, %rbx
movb %r11b, 0x63(%rdi,%rdx)
movslq 0x4(%rcx,%r9,8), %r11
movb 0x5b(%r10,%r11,4), %r11b
jmp 0x170ee
testq %r10, %r10
je 0x170ba
movb $0x2, %r11b
testl %esi, %esi
je 0x170bd
movl 0x10(%r10), %r10d
andl %r8d, %r10d
je 0x170bd
movb $-0x1, %r11b
movb %r11b, 0x63(%rdi,%rdx)
movq %rdx, %rbx
jmp 0x170ee
movslq (%rcx,%r9,8), %r11
orq $0x1, %r11
movb 0x58(%r10,%r11), %r11b
movq %r9, %rbx
shlq $0x4, %rbx
movb %r11b, 0x63(%rdi,%rdx)
movslq 0x4(%rcx,%r9,8), %r11
orq $0x1, %r11
movb 0x58(%r10,%r11), %r11b
movb %r11b, 0x6b(%rdi,%rbx)
incq %r9
addq $0x10, %rdx
cmpq $0x1, %r9
je 0x1706a
popq %rbx
retq