// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/diet.c
// Function: do_decompress_code
static void do_decompress_code(deark *c, lctx *d)
{
	struct de_lz77buffer *ringbuf = NULL;
	u8 v;
	u8 x1, x2;
	u8 a1, a2, a3, a4, a5, a6, a7, a8;

	if(d->cmpr_pos + d->cmpr_len > c->infile->len) {
		d->errflag = 1;
		d->need_errmsg = 1;
	}
	de_dbg(c, "decompressing cmpr code at %"I64_FMT, d->cmpr_pos);
	de_dbg_indent(c, 1);

	ringbuf = de_lz77buffer_create(c, 8192);
	ringbuf->userdata = (void*)d;
	ringbuf->writebyte_cb = my_lz77buf_writebytecb;

	d->dcmpr_cur_ipos = d->cmpr_pos;
	d->bbll.is_lsb = 1;
	de_bitbuf_lowlevel_empty(&d->bbll);

	while(1) {
		UI matchpos = 0;
		UI matchlen;

		if(d->errflag) goto done;

		x1 = diet_getbit(c, d);
		if(x1) { // 1... -> literal byte
			u8 b;

			b = de_getbyte_p(&d->dcmpr_cur_ipos);
			if(c->debug_level>=4) {
				de_dbg(c, "lit 0x%02x", (UI)b);
			}
			de_lz77buffer_add_literal_byte(ringbuf, b);
			continue;
		}

		x2 = diet_getbit(c, d);
		v = de_getbyte_p(&d->dcmpr_cur_ipos);

		if(x2==0) { // 00[XX]... -> 2-byte match or special code
			a1 = diet_getbit(c, d); // Always need at least 1 more bit
			if(a1) { // "long" two-byte match
				matchlen = 2;
				a2 = diet_getbit(c, d);
				a3 = diet_getbit(c, d);
				a4 = diet_getbit(c, d);
				matchpos = 2303 - (1024*(UI)a2 + 512*(UI)a3 + 256*(UI)a4 + v);
				goto ready_for_match;
			}
			else if(v!=0xff) { // "short" two-byte match
				matchlen = 2;
				matchpos = 0xff - (UI)v;
				goto ready_for_match;
			}

			// special code

			a2 = diet_getbit(c, d);
			if(a2==0) { // 00[FF]00
				de_dbg3(c, "stop code");
				goto after_decompress;
			}

			// 00[FF]01
			if(d->idd.ftype==FTYPE_EXE) {
				de_dbg3(c, "segment refresh");
				continue;
			}
			de_err(c, "Unsupported feature");
			d->errflag = 1;
			goto done;
		}

		// 01[v] -> 3 or more byte match

		a1 = diet_getbit(c, d);
		a2 = diet_getbit(c, d);

		if(a2) { // 01[v]?1
			matchpos = 511 - (256*(UI)a1 + (UI)v);
			goto ready_for_len;
		}

		a3 = diet_getbit(c, d);
		if(a3) { // 01[v]?01
			matchpos = 1023 - (256*(UI)a1 + (UI)v);
			goto ready_for_len;
		}

		// 01[v]?00
		a4 = diet_getbit(c, d);
		a5 = diet_getbit(c, d);

		if(a5) { // 01[v]?00?1
			matchpos = 2047 - (512*(UI)a1 + 256* (UI)a4 + (UI)v);
			goto ready_for_len;
		}

		// 01[v]?00?0
		a6 = diet_getbit(c, d);
		a7 = diet_getbit(c, d);

		if(a7) { // 01[v]?00?0?1
			matchpos = 4095 - (1024*(UI)a1 + 512*(UI)a4 + 256*(UI)a6 + (UI)v);
			goto ready_for_len;
		}

		// 01[v]?00?0?0
		a8 = diet_getbit(c, d);
		matchpos = 8191 - (2048*(UI)a1 + 1024*(UI)a4 + 512*(UI)a6 + 256*(UI)a8 + (UI)v);


ready_for_len:
		matchlen = read_matchlen(c, d);
		if(d->errflag) goto done;

ready_for_match:
		if(c->debug_level>=3) {
			de_dbg3(c, "match pos=%u len=%u", matchpos+1, matchlen);
		}
		if((i64)matchpos+1 > d->dcmpr_code_nbytes_written) {
			// Match refers to data before the beginning of the file --
			// DIET doesn't do this.
			d->errflag = 1;
			d->need_errmsg = 1;
			goto done;
		}
		if(matchlen > (i64)matchpos+1) {
			// Some matching data hasn't been decompressed yet.
			// This is a legitimate feature of LZ77, but DIET apparently doesn't
			// use it.
			d->errflag = 1;
			d->need_errmsg = 1;
			goto done;
		}

		de_lz77buffer_copy_from_hist(ringbuf,
			(UI)(ringbuf->curpos-1-matchpos), matchlen);
	}

after_decompress:
	de_dbg(c, "decompressed %"I64_FMT" bytes to %"I64_FMT, (d->dcmpr_cur_ipos-d->cmpr_pos),
		d->dcmpr_code_nbytes_written);

done:
	dbuf_flush(d->dcmpr_code);
	de_lz77buffer_destroy(c, ringbuf);
	de_dbg_indent(c, -1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x30(%rcx), %rax
movq -0x8(%rbp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x18(%rcx), %rax
jle 0x6a366
movq -0x10(%rbp), %rax
movb $0x1, 0x28(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x29(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rdx
leaq 0x13fe9a(%rip), %rsi    # 0x1aa213
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x8(%rbp), %rdi
movl $0x2000, %esi           # imm = 0x2000
callq 0x1785d0
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
leaq 0x7ea(%rip), %rcx       # 0x6aba0
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x70(%rax)
movq -0x10(%rbp), %rdi
addq $0x70, %rdi
callq 0x16a360
movl $0x0, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x28(%rax)
je 0x6a3f5
jmp 0x6a7bb
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1a(%rbp)
cmpb $0x0, -0x1a(%rbp)
je 0x6a451
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x68, %rsi
callq 0x165170
movb %al, -0x2d(%rbp)
movq -0x8(%rbp), %rax
cmpl $0x4, (%rax)
jl 0x6a442
movq -0x8(%rbp), %rdi
movzbl -0x2d(%rbp), %edx
leaq 0x13fdf7(%rip), %rsi    # 0x1aa232
movb $0x0, %al
callq 0x15b0d0
movq -0x18(%rbp), %rdi
movzbl -0x2d(%rbp), %esi
callq 0x178880
jmp 0x6a3df
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1b(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x68, %rsi
callq 0x165170
movb %al, -0x19(%rbp)
movzbl -0x1b(%rbp), %eax
cmpl $0x0, %eax
jne 0x6a598
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1c(%rbp)
cmpb $0x0, -0x1c(%rbp)
je 0x6a501
movl $0x2, -0x2c(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1d(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1e(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1f(%rbp)
movzbl -0x1d(%rbp), %ecx
shll $0xa, %ecx
movzbl -0x1e(%rbp), %eax
shll $0x9, %eax
addl %eax, %ecx
movzbl -0x1f(%rbp), %eax
shll $0x8, %eax
addl %eax, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0x8ff, %eax            # imm = 0x8FF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a70b
movzbl -0x19(%rbp), %eax
cmpl $0xff, %eax
je 0x6a526
movl $0x2, -0x2c(%rbp)
movzbl -0x19(%rbp), %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a70b
jmp 0x6a528
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1d(%rbp)
movzbl -0x1d(%rbp), %eax
cmpl $0x0, %eax
jne 0x6a558
movq -0x8(%rbp), %rdi
leaq 0x13fcf1(%rip), %rsi    # 0x1aa23d
movb $0x0, %al
callq 0x15b400
jmp 0x6a791
movq -0x10(%rbp), %rax
cmpl $0x3, 0x4(%rax)
jne 0x6a579
movq -0x8(%rbp), %rdi
leaq 0x13fcda(%rip), %rsi    # 0x1aa247
movb $0x0, %al
callq 0x15b400
jmp 0x6a3df
movq -0x8(%rbp), %rdi
leaq 0x13fcd3(%rip), %rsi    # 0x1aa257
movb $0x0, %al
callq 0x15bfb0
movq -0x10(%rbp), %rax
movb $0x1, 0x28(%rax)
jmp 0x6a7bb
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1c(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1d(%rbp)
cmpb $0x0, -0x1d(%rbp)
je 0x6a5da
movzbl -0x1c(%rbp), %ecx
shll $0x8, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0x1ff, %eax            # imm = 0x1FF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a6ea
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1e(%rbp)
cmpb $0x0, -0x1e(%rbp)
je 0x6a60c
movzbl -0x1c(%rbp), %ecx
shll $0x8, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0x3ff, %eax            # imm = 0x3FF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a6ea
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x1f(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x20(%rbp)
cmpb $0x0, -0x20(%rbp)
je 0x6a657
movzbl -0x1c(%rbp), %ecx
shll $0x9, %ecx
movzbl -0x1f(%rbp), %eax
shll $0x8, %eax
addl %eax, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0x7ff, %eax            # imm = 0x7FF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a6ea
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x21(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x22(%rbp)
cmpb $0x0, -0x22(%rbp)
je 0x6a6a8
movzbl -0x1c(%rbp), %ecx
shll $0xa, %ecx
movzbl -0x1f(%rbp), %eax
shll $0x9, %eax
addl %eax, %ecx
movzbl -0x21(%rbp), %eax
shll $0x8, %eax
addl %eax, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0xfff, %eax            # imm = 0xFFF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0x6a6ea
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6abf0
movb %al, -0x23(%rbp)
movzbl -0x1c(%rbp), %ecx
shll $0xb, %ecx
movzbl -0x1f(%rbp), %eax
shll $0xa, %eax
addl %eax, %ecx
movzbl -0x21(%rbp), %eax
shll $0x9, %eax
addl %eax, %ecx
movzbl -0x23(%rbp), %eax
shll $0x8, %eax
addl %eax, %ecx
movzbl -0x19(%rbp), %eax
addl %eax, %ecx
movl $0x1fff, %eax           # imm = 0x1FFF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6ac70
movl %eax, -0x2c(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x28(%rax)
je 0x6a709
jmp 0x6a7bb
jmp 0x6a70b
movq -0x8(%rbp), %rax
cmpl $0x3, (%rax)
jl 0x6a72f
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %edx
addl $0x1, %edx
movl -0x2c(%rbp), %ecx
leaq 0x13fb43(%rip), %rsi    # 0x1aa26b
movb $0x0, %al
callq 0x15b400
movl -0x28(%rbp), %eax
addq $0x1, %rax
movq -0x10(%rbp), %rcx
cmpq 0x60(%rcx), %rax
jle 0x6a752
movq -0x10(%rbp), %rax
movb $0x1, 0x28(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x29(%rax)
jmp 0x6a7bb
movl -0x2c(%rbp), %eax
movl -0x28(%rbp), %ecx
addq $0x1, %rcx
cmpq %rcx, %rax
jle 0x6a773
movq -0x10(%rbp), %rax
movb $0x1, 0x28(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x29(%rax)
jmp 0x6a7bb
movq -0x18(%rbp), %rdi
movq -0x18(%rbp), %rax
movl 0x10(%rax), %esi
subl $0x1, %esi
subl -0x28(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x1788e0
jmp 0x6a3df
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x68(%rax), %rdx
movq -0x10(%rbp), %rax
subq 0x40(%rax), %rdx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rcx
leaq 0x13458f(%rip), %rsi    # 0x19ed43
movb $0x0, %al
callq 0x15b0d0
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rdi
callq 0x167c30
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x178950
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)