// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/dms.c
// Function: mediumlz77_codec_addbuf
static void mediumlz77_codec_addbuf(struct de_dfilter_ctx *dfctx,
	const u8 *buf, i64 buf_len)
{
	struct medium_ctx *mctx = (struct medium_ctx *)dfctx->codec_private;
	struct medium_state_machine *mdst = &mctx->mdst;
	i64 bufpos = 0;
	UI n;
	UI offset_rel;
	UI length;

	if(dfctx->finished_flag || mctx->errflag) {
		goto done;
	}

	while(1) {
		if(medium_have_enough_output(mctx)) {
			dfctx->finished_flag = 1;
			goto done;
		}

		// Top off the bitbuf, if possible. 32 is an arbitrary number that's
		// large enough for this format.
		while(bufpos<buf_len && mctx->bbll.nbits_in_bitbuf<32) {
			de_bitbuf_lowlevel_add_byte(&mctx->bbll, buf[bufpos++]);
		}

		if(mdst->state==MEDLZST_WAITING_FOR_OCODE1) goto read_ocode1;
		if(mdst->state==MEDLZST_WAITING_FOR_OCODE2) goto read_ocode2;

		// Make sure we have enough source data to read the flag bit,
		// plus either the literal byte or the first_code.
		if(mctx->bbll.nbits_in_bitbuf < 9) goto done;

		n = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 1);

		if(n) { // literal byte
			u8 b;

			b = (u8)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 8);
			de_lz77buffer_add_literal_byte(mctx->ringbuf, (u8)b);
			continue;
		}

		// TODO: This seems overly complicated. Is there a simpler way to
		// implement this?

		mdst->first_code = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, 8);
		fmtutil_get_lzhuf_d_code_and_len(mdst->first_code, &mdst->d_code1, &mdst->d_len1);

	read_ocode1:
		mdst->ocode1_nbits = mdst->d_len1;
		if(mctx->bbll.nbits_in_bitbuf < mdst->ocode1_nbits) {
			mdst->state = MEDLZST_WAITING_FOR_OCODE1;
			goto done;
		}
		mdst->ocode1 = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, mdst->ocode1_nbits);

		mdst->tmp_code = ((mdst->first_code << mdst->ocode1_nbits) | mdst->ocode1) & 0xff;
		fmtutil_get_lzhuf_d_code_and_len(mdst->tmp_code, &mdst->d_code2, &mdst->d_len2);

	read_ocode2:
		mdst->ocode2_nbits = mdst->d_len2;
		if(mctx->bbll.nbits_in_bitbuf < mdst->ocode2_nbits) {
			mdst->state = MEDLZST_WAITING_FOR_OCODE2;
			goto done;
		}
		mdst->ocode2 = (UI)de_bitbuf_lowlevel_get_bits(&mctx->bbll, mdst->ocode2_nbits);

		offset_rel = (mdst->d_code2 << 8) | (((mdst->tmp_code << mdst->ocode2_nbits) | mdst->ocode2) & 0xff);
		length = mdst->d_code1 + 3;
		de_lz77buffer_copy_from_hist(mctx->ringbuf, mctx->ringbuf->curpos - 1 - offset_rel, length);
		mdst->state = MEDLZST_NEUTRAL;
	}

done:
	if(!dfctx->finished_flag && !mctx->errflag) {
		if(bufpos<buf_len) {
			// It shouldn't be possible to get here. If we do, it means some input
			// bytes will be lost.
			de_dfilter_set_generic_error(dfctx->c, mctx->dres, mctx->modname);
			mctx->errflag = 1;
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
addq $0x48, %rax
movq %rax, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x8(%rbp), %rax
movzbl 0x20(%rax), %eax
cmpl $0x0, %eax
jne 0x66d5b
movq -0x20(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x66d60
jmp 0x66fb4
jmp 0x66d62
movq -0x20(%rbp), %rdi
callq 0x66cc0
cmpl $0x0, %eax
je 0x66d7d
movq -0x8(%rbp), %rax
movb $0x1, 0x20(%rax)
jmp 0x66fb4
jmp 0x66d7f
movq -0x30(%rbp), %rcx
xorl %eax, %eax
cmpq -0x18(%rbp), %rcx
movb %al, -0x3e(%rbp)
jge 0x66d9c
movq -0x20(%rbp), %rax
cmpl $0x20, 0x3c(%rax)
setb %al
movb %al, -0x3e(%rbp)
movb -0x3e(%rbp), %al
testb $0x1, %al
jne 0x66da5
jmp 0x66dcb
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movq -0x10(%rbp), %rax
movq -0x30(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x30(%rbp)
movzbl (%rax,%rcx), %esi
callq 0x16a230
jmp 0x66d7f
movq -0x28(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x66dd9
jmp 0x66e73
movq -0x28(%rbp), %rax
cmpl $0x2, (%rax)
jne 0x66de7
jmp 0x66eff
movq -0x20(%rbp), %rax
cmpl $0x9, 0x3c(%rax)
jae 0x66df6
jmp 0x66fb4
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movl $0x1, %esi
callq 0x16a2a0
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
je 0x66e3c
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movl $0x8, %esi
callq 0x16a2a0
movb %al, -0x3d(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movzbl -0x3d(%rbp), %esi
callq 0x178880
jmp 0x66d62
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movl $0x8, %esi
callq 0x16a2a0
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x28(%rbp), %rax
movl 0x4(%rax), %edi
movq -0x28(%rbp), %rsi
addq $0x1c, %rsi
movq -0x28(%rbp), %rdx
addq $0x20, %rdx
callq 0x18b2d0
movq -0x28(%rbp), %rax
movl 0x20(%rax), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x20(%rbp), %rax
movl 0x3c(%rax), %eax
movq -0x28(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jae 0x66ea0
movq -0x28(%rbp), %rax
movl $0x1, (%rax)
jmp 0x66fb4
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movq -0x28(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x16a2a0
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x28(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x28(%rbp), %rcx
movl 0x8(%rcx), %ecx
shll %cl, %eax
movl %eax, %ecx
movq -0x28(%rbp), %rax
orl 0xc(%rax), %ecx
andl $0xff, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x28(%rbp), %rax
movl 0x18(%rax), %edi
movq -0x28(%rbp), %rsi
addq $0x24, %rsi
movq -0x28(%rbp), %rdx
addq $0x28, %rdx
callq 0x18b2d0
movq -0x28(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
movl 0x3c(%rax), %eax
movq -0x28(%rbp), %rcx
cmpl 0x10(%rcx), %eax
jae 0x66f2c
movq -0x28(%rbp), %rax
movl $0x2, (%rax)
jmp 0x66fb4
movq -0x20(%rbp), %rdi
addq $0x38, %rdi
movq -0x28(%rbp), %rax
movl 0x10(%rax), %esi
callq 0x16a2a0
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x28(%rbp), %rax
movl 0x24(%rax), %eax
shll $0x8, %eax
movq -0x28(%rbp), %rcx
movl 0x18(%rcx), %edx
movq -0x28(%rbp), %rcx
movl 0x10(%rcx), %ecx
shll %cl, %edx
movl %edx, %ecx
movq -0x28(%rbp), %rdx
orl 0x14(%rdx), %ecx
andl $0xff, %ecx
orl %ecx, %eax
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movl 0x1c(%rax), %eax
addl $0x3, %eax
movl %eax, -0x3c(%rbp)
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x30(%rax), %rax
movl 0x10(%rax), %esi
subl $0x1, %esi
subl -0x38(%rbp), %esi
movl -0x3c(%rbp), %edx
callq 0x1788e0
movq -0x28(%rbp), %rax
movl $0x0, (%rax)
jmp 0x66d62
movq -0x8(%rbp), %rax
cmpb $0x0, 0x20(%rax)
jne 0x66ffb
movq -0x20(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x66ffb
movq -0x30(%rbp), %rax
cmpq -0x18(%rbp), %rax
jge 0x66ff9
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rdx
callq 0x177560
movq -0x20(%rbp), %rax
movl $0x1, 0x20(%rax)
jmp 0x66ffb
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)