// File: /workspace/github_c_makefile_star2_O1/tvlabs[P]edge264/./edge264_slice.c
// Function: parse_NxN_residual_cabac
static void CAFUNC(parse_NxN_residual)
{
	static const int8_t Intra4x4Modes[9][16] = {
		{I4x4_V_8  , I4x4_V_8   , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_V_8   , I4x4_V_8   , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_V_8   , I4x4_V_8   , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_V_8   , I4x4_V_8   , I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_H_8  , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8, I4x4_H_8   , I4x4_DCAB_8},
		{I4x4_DC_8 , I4x4_DCA_8 , I4x4_DCB_8 , I4x4_DCAB_8, I4x4_DC_8  , I4x4_DCA_8 , I4x4_DCB_8 , I4x4_DCAB_8, I4x4_DC_8  , I4x4_DCA_8 , I4x4_DCB_8 , I4x4_DCAB_8, I4x4_DC_8  , I4x4_DCA_8 , I4x4_DCB_8 , I4x4_DCAB_8},
		{I4x4_DDL_8, I4x4_DDL_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DDLC_8, I4x4_DDLC_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DDL_8 , I4x4_DDL_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DDLC_8, I4x4_DDLC_8, I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_DDR_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DDR_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_VR_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_VR_8  , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_HD_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_HD_8  , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_VL_8 , I4x4_VL_8  , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_VLC_8 , I4x4_VLC_8 , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_VL_8  , I4x4_VL_8  , I4x4_DCAB_8, I4x4_DCAB_8, I4x4_VLC_8 , I4x4_VLC_8 , I4x4_DCAB_8, I4x4_DCAB_8},
		{I4x4_HU_8 , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8, I4x4_HU_8  , I4x4_DCAB_8},
	};
	static const int8_t Intra8x8Modes[9][16] = {
		{I8x8_V_8  , I8x8_V_8    , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_V_C_8  , I8x8_V_C_8  , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_V_D_8  , I8x8_V_D_8  , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_V_CD_8  , I8x8_V_CD_8  , I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_H_8  , I8x8_DC_AB_8, I8x8_H_8    , I8x8_DC_AB_8, I8x8_H_8    , I8x8_DC_AB_8, I8x8_H_8    , I8x8_DC_AB_8, I8x8_H_D_8  , I8x8_DC_AB_8, I8x8_H_D_8  , I8x8_DC_AB_8, I8x8_H_D_8   , I8x8_DC_AB_8 , I8x8_H_D_8  , I8x8_DC_AB_8},
		{I8x8_DC_8 , I8x8_DC_A_8 , I8x8_DC_B_8 , I8x8_DC_AB_8, I8x8_DC_C_8 , I8x8_DC_AC_8, I8x8_DC_B_8 , I8x8_DC_AB_8, I8x8_DC_D_8 , I8x8_DC_AD_8, I8x8_DC_BD_8, I8x8_DC_AB_8, I8x8_DC_CD_8 , I8x8_DC_ACD_8, I8x8_DC_BD_8, I8x8_DC_AB_8},
		{I8x8_DDL_8, I8x8_DDL_8  , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DDL_C_8, I8x8_DDL_C_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DDL_D_8, I8x8_DDL_D_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DDL_CD_8, I8x8_DDL_CD_8, I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_DDR_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DDR_C_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8 , I8x8_DC_AB_8 , I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_VR_8 , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_VR_C_8 , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8 , I8x8_DC_AB_8 , I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_HD_8 , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_HD_8   , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_DC_AB_8 , I8x8_DC_AB_8 , I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_VL_8 , I8x8_VL_8   , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_VL_C_8 , I8x8_VL_C_8 , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_VL_D_8 , I8x8_VL_D_8 , I8x8_DC_AB_8, I8x8_DC_AB_8, I8x8_VL_CD_8 , I8x8_VL_CD_8 , I8x8_DC_AB_8, I8x8_DC_AB_8},
		{I8x8_HU_8 , I8x8_DC_AB_8, I8x8_HU_8   , I8x8_DC_AB_8, I8x8_HU_8   , I8x8_DC_AB_8, I8x8_HU_8   , I8x8_DC_AB_8, I8x8_HU_D_8 , I8x8_DC_AB_8, I8x8_HU_D_8 , I8x8_DC_AB_8, I8x8_HU_D_8  , I8x8_DC_AB_8 , I8x8_HU_D_8 , I8x8_DC_AB_8},
	};
	
	if (mb->f.CodedBlockPatternChromaDC | (mb->bits[0] & 0xac)) {
		CACALL(parse_mb_qp_delta);
		log_mb(ctx, "    coeffLevels:\n");
	}
	#if CABAC
		else
			ctx->mb_qp_delta_nz = 0;
	#endif
	
	// next few blocks will share many parameters, so we cache them
	for (int iYCbCr = 0; iYCbCr < 3; iYCbCr++) {
		if (!mb->f.transform_size_8x8_flag) {
			#if CABAC
				ctx->ctxIdxOffsets_l = ctxIdxOffsets_4x4[iYCbCr][0];
				ctx->coeff_abs_inc_l = (i8x8){6, 7, 8, 9, 9};
				ctx->sig_inc_v[0] = ctx->last_inc_v[0] = sig_inc_4x4;
			#endif
			ctx->scan_v[0] = scan_4x4[0];
			
			// Decoding directly follows parsing to avoid duplicate loops.
			for (int i4x4 = 0; i4x4 < 16; i4x4++) {
				size_t stride = ctx->t.stride[iYCbCr];
				uint8_t *samples = ctx->samples_mb[iYCbCr] + y444[i4x4] * stride + x444[i4x4];
				if (!mb->mbIsInterFlag)
					decode_intra4x4(Intra4x4Modes[mb->Intra4x4PredMode[i4x4]][ctx->unavail4x4[i4x4]], samples, stride, ctx->t.samples_clip_v[iYCbCr]);
				if (mb->bits[0] & 1 << bit8x8[i4x4 >> 2]) {
					int nA = *((int8_t *)mb->nC + iYCbCr * 16 + ctx->A4x4_int8[i4x4]);
					int nB = *((int8_t *)mb->nC + iYCbCr * 16 + ctx->B4x4_int8[i4x4]);
					// DC blocks are marginal here (about 16%) so we do not handle them separately
					#if !CABAC
						if (parse_residual_block_4x4_cavlc(ctx, iYCbCr * 16 + i4x4, nA, nB, 0))
							add_idct4x4(ctx, iYCbCr, -1, samples); // FIXME 4:4:4
					#else
						if (get_ae(ctx, ctx->ctxIdxOffsets[0] + ctx->nC_inc[iYCbCr][i4x4] + nA + nB * 2)) {
							mb->nC[iYCbCr * 16 + i4x4] = 1;
							parse_residual_coeffs_cabac(ctx, 0, 15);
							add_idct4x4(ctx, iYCbCr, -1, samples); // FIXME 4:4:4
						}
					#endif
				}
			}
		} else {
			#if CABAC
				ctx->ctxIdxOffsets_l = ctxIdxOffsets_8x8[iYCbCr][0];
				ctx->coeff_abs_inc_l = (i8x8){6, 7, 8, 9, 9};
				ctx->sig_inc_v[0] = sig_inc_8x8[0][0];
				ctx->last_inc_v[0] = last_inc_8x8[0];
				ctx->scan_v[0] = scan_8x8_cabac[0][0];
			#endif
			
			for (int i8x8 = 0; i8x8 < 4; i8x8++) {
				size_t stride = ctx->t.stride[iYCbCr];
				uint8_t *samples = ctx->samples_mb[iYCbCr] + y444[i8x8 * 4] * stride + x444[i8x8 * 4];
				if (!mb->mbIsInterFlag)
					decode_intra8x8(Intra8x8Modes[mb->Intra4x4PredMode[i8x8 * 4 + 1]][ctx->unavail4x4[i8x8 * 5]], samples, stride, ctx->t.samples_clip_v[iYCbCr]);
				if (mb->bits[0] & 1 << bit8x8[i8x8]) {
					#if !CABAC
						for (int i4x4 = 0; i4x4 < 4; i4x4++) {
							ctx->scan_v[0] = scan_8x8_cavlc[0][i4x4];
							int nA = *((int8_t *)mb->nC + iYCbCr * 16 + ctx->A4x4_int8[i8x8 * 4 + i4x4]);
							int nB = *((int8_t *)mb->nC + iYCbCr * 16 + ctx->B4x4_int8[i8x8 * 4 + i4x4]);
							parse_residual_block_4x4_cavlc(ctx, iYCbCr * 16 + i8x8 * 4 + i4x4, nA, nB, 0);
						}
						add_idct8x8(ctx, iYCbCr, samples);
					#else
						if (ctx->t.ChromaArrayType < 3 || get_ae(ctx, ctx->ctxIdxOffsets[0] + (mb->bits[1] >> inc8x8[iYCbCr * 4 + i8x8] & 3))) {
							mb->bits[1] |= 1 << bit8x8[iYCbCr * 4 + i8x8];
							mb->nC_s[iYCbCr * 4 + i8x8] = 0x01010101;
							parse_residual_coeffs_cabac(ctx, 0, 63);
							add_idct8x8(ctx, iYCbCr, samples);
						}
					#endif
				}
			}
		}
		
		// nice optimisation for 4:4:4 modes
		if (ctx->t.ChromaArrayType <3)
			CAJUMP(parse_chroma_residual);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rdi, %rbx
movq 0x680(%rdi), %rax
movsbl 0x26(%rax), %ecx
movl $0xac, %edx
andl 0x8(%rax), %edx
orl %ecx, %edx
je 0x17007
movq %rbx, %rdi
callq 0x17392
jmp 0x1700e
movb $0x0, 0x651(%rbx)
leaq 0x6d0(%rbx), %rax
movq %rax, 0x28(%rsp)
leaq 0x700(%rbx), %rax
movq %rax, 0x18(%rsp)
movl $0x40, %eax
movq %rax, 0x20(%rsp)
movq $0x0, 0x10(%rsp)
movabsq $0x909080706, %rax      # imm = 0x909080706
vmovq %rax, %xmm0
vmovdqa %xmm0, 0x30(%rsp)
movq $0x0, 0x8(%rsp)
xorl %r14d, %r14d
movq 0x680(%rbx), %rax
cmpb $0x0, 0x24(%rax)
je 0x171ee
movq %r14, %rax
shlq $0x4, %rax
leaq 0x20097(%rip), %rcx     # 0x37110
vmovsd (%rax,%rcx), %xmm0
vunpcklpd 0x30(%rsp), %xmm0, %xmm0 # xmm0 = xmm0[0],mem[0]
vmovaps %xmm0, 0x1a10(%rbx)
vmovaps 0x1c82c(%rip), %xmm0    # 0x338c0
vmovaps %xmm0, 0x1a20(%rbx)
vmovaps 0x1c82c(%rip), %xmm0    # 0x338d0
vmovaps %xmm0, 0x1a60(%rbx)
vmovdqa 0x1c82c(%rip), %xmm0    # 0x338e0
vmovdqa %xmm0, 0x1aa0(%rbx)
xorl %r13d, %r13d
movq 0x28(%rsp), %rbp
xorl %r12d, %r12d
movzwl 0x34(%rbx,%r14,2), %edx
leaq 0x1c85c(%rip), %rax     # 0x33930
movsbq (%r13,%rax), %rax
imulq %rdx, %rax
addq 0x668(%rbx,%r14,8), %rax
leaq 0x1c833(%rip), %rcx     # 0x33920
movsbq (%r13,%rcx), %r15
addq %rax, %r15
movq 0x680(%rbx), %rax
cmpb $0x0, 0x2(%rax)
jne 0x17128
movsbq 0x31(%rax,%r12,4), %rax
movsbq (%rbp), %rcx
shlq $0x4, %rax
leaq 0x1ff37(%rip), %rsi     # 0x37050
addq %rsi, %rax
movsbl (%rcx,%rax), %edi
movq %r15, %rsi
callq 0x130f1
movq 0x680(%rbx), %rax
movl 0x8(%rax), %ecx
leaq 0x1f2c7(%rip), %rdx     # 0x36400
movzbl (%r12,%rdx), %edx
btl %edx, %ecx
jae 0x171d4
cmpb $0x3, 0x2a(%rbx)
jl 0x1717d
movswl 0x1a10(%rbx), %ecx
movq 0x8(%rsp), %rdx
addq %r12, %rdx
leaq 0x1fe4d(%rip), %rsi     # 0x36fb0
movb (%rsi,%rdx), %dl
shrxl %edx, 0xc(%rax), %esi
andl $0x3, %esi
addl %ecx, %esi
movq %rbx, %rdi
callq 0x1680d
testl %eax, %eax
je 0x171d4
movq 0x8(%rsp), %rax
addq %r12, %rax
leaq 0x1f274(%rip), %rcx     # 0x36400
movb (%rcx,%rax), %al
movl $0x1, %ecx
shlxl %eax, %ecx, %eax
movq 0x680(%rbx), %rcx
orl %eax, 0xc(%rcx)
movq 0x680(%rbx), %rax
addq 0x20(%rsp), %rax
movl $0x1010101, (%rax,%r12,4) # imm = 0x1010101
movq %rbx, %rdi
xorl %esi, %esi
movl $0x3f, %edx
callq 0x17435
movq %rbx, %rdi
movl %r14d, %esi
movq %r15, %rdx
callq 0x13995
incq %r12
addq $0x5, %rbp
addq $0x4, %r13
cmpq $0x4, %r12
jne 0x170c7
jmp 0x17342
movq %r14, %r13
shlq $0x4, %r13
leaq 0x1fee4(%rip), %rax     # 0x370e0
vmovsd (%r13,%rax), %xmm0
vunpcklpd 0x30(%rsp), %xmm0, %xmm0 # xmm0 = xmm0[0],mem[0]
vmovaps %xmm0, 0x1a10(%rbx)
vmovaps 0x1c697(%rip), %xmm0    # 0x338b0
vmovaps %xmm0, 0x1a60(%rbx)
vmovaps %xmm0, 0x1a20(%rbx)
vmovdqa 0x1c2ff(%rip), %xmm0    # 0x33530
vmovdqa %xmm0, 0x1aa0(%rbx)
xorl %r12d, %r12d
movzwl 0x34(%rbx,%r14,2), %edx
leaq 0x1c6e7(%rip), %rax     # 0x33930
movsbq (%r12,%rax), %rax
imulq %rdx, %rax
addq 0x668(%rbx,%r14,8), %rax
leaq 0x1c6bf(%rip), %rcx     # 0x33920
movsbq (%r12,%rcx), %r15
addq %rax, %r15
movq 0x680(%rbx), %rax
cmpb $0x0, 0x2(%rax)
jne 0x1729f
movsbq 0x30(%rax,%r12), %rax
movsbq 0x6d0(%rbx,%r12), %rcx
shlq $0x4, %rax
leaq 0x1fd30(%rip), %rsi     # 0x36fc0
addq %rsi, %rax
movsbl (%rcx,%rax), %edi
movq %r15, %rsi
callq 0x12b90
movq 0x680(%rbx), %rax
movl 0x8(%rax), %ecx
movl %r12d, %edx
shrl $0x2, %edx
leaq 0x1f14a(%rip), %rsi     # 0x36400
movzbl (%rdx,%rsi), %edx
btl %edx, %ecx
jae 0x17335
addq %r13, %rax
movswq 0xb40(%rbx,%r12,2), %rcx
movsbl 0x40(%rcx,%rax), %ecx
movslq 0xb80(%rbx,%r12,4), %rdx
movsbl 0x40(%rdx,%rax), %eax
movswl 0x1a10(%rbx), %edx
addl %ecx, %edx
movq 0x18(%rsp), %rcx
movsbl (%rcx,%r12), %ecx
leal (%rdx,%rax,2), %esi
addl %ecx, %esi
movq %rbx, %rdi
callq 0x1680d
testl %eax, %eax
je 0x17335
movq 0x680(%rbx), %rax
addq 0x10(%rsp), %rax
movb $0x1, 0x40(%r12,%rax)
movq %rbx, %rdi
xorl %esi, %esi
movl $0xf, %edx
callq 0x17435
movq %rbx, %rdi
movl %r14d, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %r15, %rcx
callq 0x12ece
incq %r12
cmpq $0x10, %r12
jne 0x1723c
cmpb $0x2, 0x2a(%rbx)
jle 0x1737c
incq %r14
addq $0x4, 0x8(%rsp)
addq $0x10, 0x20(%rsp)
addq $0x10, 0x18(%rsp)
addq $0x10, 0x10(%rsp)
cmpq $0x3, %r14
jne 0x1705a
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x17a64