// File: /workspace/github_cpp_makefile_star2_O3/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 0x16bc4
movl 0x10(%rcx), %edx
movl %edx, %r8d
andl $0x3, %r8d
je 0x16bb6
cmpl $0x1, %r8d
jne 0x16bd4
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 0x16be3
movb $0x2, %cl
testl %esi, %esi
je 0x16bc6
andl $0xf0, %edx
je 0x16bc6
movb $-0x1, %cl
movzbl %cl, %ecx
imull $0x1010101, %ecx, %ecx  # imm = 0x1010101
movl %ecx, 0x5c(%rdi)
jmp 0x16be6
movb 0x5a(%rcx), %dl
movb %dl, 0x5c(%rdi)
movb %dl, 0x5d(%rdi)
movb 0x5b(%rcx), %cl
movb %cl, 0x5e(%rdi)
movb %cl, 0x5f(%rdi)
movq 0x48(%rdi), %rcx
movb $0x1, %dl
xorl %r8d, %r8d
movq 0x40(%rax,%r8,8), %r9
testq %r9, %r9
je 0x16c3d
movl 0x10(%r9), %r10d
movl %r10d, %r11d
andl $0x3, %r11d
je 0x16c2d
cmpl $0x1, %r11d
jne 0x16c4b
movslq (%rcx,%r8,8), %r10
movb 0x5b(%r9,%r10,4), %r10b
movq %r8, %r11
shlq $0x4, %r11
movb %r10b, 0x63(%rdi,%r11)
movslq 0x4(%rcx,%r8,8), %r8
movb 0x5b(%r9,%r8,4), %r9b
jmp 0x16c72
movb $0x2, %r9b
testl %esi, %esi
je 0x16c40
andl $0xf0, %r10d
je 0x16c40
movb $-0x1, %r9b
shlq $0x4, %r8
movb %r9b, 0x63(%rdi,%r8)
jmp 0x16c75
movslq (%rcx,%r8,8), %r10
orq $0x1, %r10
movb 0x58(%r9,%r10), %r10b
movq %r8, %r11
shlq $0x4, %r11
movb %r10b, 0x63(%rdi,%r11)
movslq 0x4(%rcx,%r8,8), %r8
orq $0x1, %r8
movb 0x58(%r9,%r8), %r9b
movq %r11, %r8
movb %r9b, 0x6b(%rdi,%r8)
movl $0x1, %r8d
testb $0x1, %dl
movl $0x0, %edx
jne 0x16bef
retq
nop