// File: lukasz-wiecaszek[P]h264iframedecoder/picture_cabac.cpp
// Function: ymn::h264::picture_cabac::decode_cbp_luma()
int picture_cabac::decode_cbp_luma()
{
    const int ctxIdxOffset = 73;
    int cbp_a, cbp_b, cbp = 0;
    int ctxIdxInc = 0;
    mb* curr_mb = m_context_variables.curr_mb;

    if (curr_mb->left)
        cbp_a = (((curr_mb->left_pair[0]->cbp_luma >> (m_context_variables.left_blocks[0] & (~1))) & 2) << 0) |
                (((curr_mb->left_pair[1]->cbp_luma >> (m_context_variables.left_blocks[2] & (~1))) & 2) << 2);
    else
        cbp_a = 0x0F;

    if (curr_mb->top)
        cbp_b = curr_mb->top->cbp_luma;
    else
        cbp_b = 0x0F;

    ctxIdxInc = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04);
    cbp += m_cabac_decoder.decode_decision(ctxIdxOffset + ctxIdxInc);
    ctxIdxInc = !(cbp   & 0x01) + 2 * !(cbp_b & 0x08);
    cbp += m_cabac_decoder.decode_decision(ctxIdxOffset + ctxIdxInc) << 1;
    ctxIdxInc = !(cbp_a & 0x08) + 2 * !(cbp   & 0x01);
    cbp += m_cabac_decoder.decode_decision(ctxIdxOffset + ctxIdxInc) << 2;
    ctxIdxInc = !(cbp   & 0x04) + 2 * !(cbp   & 0x02);
    cbp += m_cabac_decoder.decode_decision(ctxIdxOffset + ctxIdxInc) << 3;

    return cbp;
}

// Assembly:
subq $0x38, %rsp
movq %rdi, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
movl $0x49, 0x2c(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movq 0x28(%rax), %rax
movq %rax, 0x10(%rsp)
movq 0x10(%rsp), %rax
cmpq $0x0, 0x38(%rax)
je 0x20d1f
movq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rax
movl 0x6c(%rax), %eax
movq 0x48(%rcx), %rcx
movl (%rcx), %ecx
andl $-0x2, %ecx
sarl %cl, %eax
movq 0x8(%rsp), %rcx
andl $0x2, %eax
shll $0x0, %eax
movq 0x10(%rsp), %rdx
movq 0x48(%rdx), %rdx
movl 0x6c(%rdx), %edx
movq 0x48(%rcx), %rcx
movl 0x8(%rcx), %ecx
andl $-0x2, %ecx
sarl %cl, %edx
movl %edx, %ecx
andl $0x2, %ecx
shll $0x2, %ecx
orl %ecx, %eax
movl %eax, 0x28(%rsp)
jmp 0x20d27
movl $0xf, 0x28(%rsp)
movq 0x10(%rsp), %rax
cmpq $0x0, 0x50(%rax)
je 0x20d45
movq 0x10(%rsp), %rax
movq 0x50(%rax), %rax
movl 0x6c(%rax), %eax
movl %eax, 0x24(%rsp)
jmp 0x20d4d
movl $0xf, 0x24(%rsp)
movq 0x8(%rsp), %rdi
movl 0x28(%rsp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl 0x24(%rsp), %ecx
andl $0x4, %ecx
cmpl $0x0, %ecx
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
shll %ecx
addl %ecx, %eax
movl %eax, 0x1c(%rsp)
addq $0xdc0, %rdi            # imm = 0xDC0
movl 0x1c(%rsp), %esi
addl $0x49, %esi
callq 0x18cd0
movq 0x8(%rsp), %rdi
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x20(%rsp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl 0x24(%rsp), %ecx
andl $0x8, %ecx
cmpl $0x0, %ecx
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
shll %ecx
addl %ecx, %eax
movl %eax, 0x1c(%rsp)
addq $0xdc0, %rdi            # imm = 0xDC0
movl 0x1c(%rsp), %esi
addl $0x49, %esi
callq 0x18cd0
movq 0x8(%rsp), %rdi
shll %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x28(%rsp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl 0x20(%rsp), %ecx
andl $0x1, %ecx
cmpl $0x0, %ecx
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
shll %ecx
addl %ecx, %eax
movl %eax, 0x1c(%rsp)
addq $0xdc0, %rdi            # imm = 0xDC0
movl 0x1c(%rsp), %esi
addl $0x49, %esi
callq 0x18cd0
movq 0x8(%rsp), %rdi
shll $0x2, %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x20(%rsp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl 0x20(%rsp), %ecx
andl $0x2, %ecx
cmpl $0x0, %ecx
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
shll %ecx
addl %ecx, %eax
movl %eax, 0x1c(%rsp)
addq $0xdc0, %rdi            # imm = 0xDC0
movl 0x1c(%rsp), %esi
addl $0x49, %esi
callq 0x18cd0
shll $0x3, %eax
addl 0x20(%rsp), %eax
movl %eax, 0x20(%rsp)
movl 0x20(%rsp), %eax
addq $0x38, %rsp
retq
nopw %cs:(%rax,%rax)