// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/lzexe.c
// Function: do_decompress_code
static void do_decompress_code(deark *c, lctx *d)
{
	i64 ipos1;
	struct de_lz77buffer *ringbuf = NULL;

	// (I'd expect ipos1 to always equal d->host_ei->start_of_dos_code, but anyway...)
	ipos1 = d->ephdr_pos -  d->ephdr.cmpr_len_para*16;
	de_dbg(c, "decompressing cmpr code at %"I64_FMT, ipos1);
	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 = ipos1;
	d->bbll.is_lsb = 1;
	de_bitbuf_lowlevel_empty(&d->bbll);

	while(1) {
		u8 x, x2, x3;
		UI matchpos;
		UI matchlen;
		u8 matchtype = 1;

		if(d->errflag) goto done;

		x = lzexe_getbit(c, d);
		if(x) { // 1...
			u8 b;

			b = de_getbyte_p(&d->dcmpr_cur_ipos);
			de_lz77buffer_add_literal_byte(ringbuf, (u8)b);
			continue;
		}

		x = lzexe_getbit(c, d);
		if(x==0) { // 00...
			x2 = lzexe_getbit(c, d);
			x3 = lzexe_getbit(c, d);
			matchlen = ((UI)x2<<1) + (UI)x3 + 2;
			matchpos = 0xffU-(UI)de_getbyte_p(&d->dcmpr_cur_ipos);
		}
		else { // 01...
			u8 lb, hb;

			lb = de_getbyte_p(&d->dcmpr_cur_ipos);
			hb = de_getbyte_p(&d->dcmpr_cur_ipos);

			matchpos = 0x1fffU - ((((UI)(hb & 0xf8))<<5) | (UI)lb);

			if((hb & 0x07)==0) {
				u8 xb;

				matchtype = 3;
				xb = de_getbyte_p(&d->dcmpr_cur_ipos);

				if(xb==0) {
					de_dbg3(c, "eof code");
					goto after_decompress;
				}
				else if(xb==1) {
					continue; // something about segments...
				}
				else {
					matchlen = (UI)xb + 1;
				}
			}
			else {
				matchtype = 2;
				matchlen = (UI)(hb & 0x07) + 2;
			}
		}

		if(c->debug_level>=3) {
			de_dbg3(c, "match (%u) pos=%u len=%u", (UI)matchtype, matchpos+1, matchlen);
		}
		de_lz77buffer_copy_from_hist(ringbuf,
				(UI)(ringbuf->curpos-1-matchpos), matchlen);
	}

after_decompress:
	dbuf_flush(d->dcmpr_code);
	de_dbg(c, "decompressed %"I64_FMT" bytes to %"I64_FMT, (d->dcmpr_cur_ipos-ipos1),
		d->dcmpr_code->len);

done:
	de_lz77buffer_destroy(c, ringbuf);
	de_dbg_indent(c, -1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x58(%rcx), %rcx
shlq $0x4, %rcx
subq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0xd4d71(%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, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x20(%rbp), %rax
leaq 0x7c1(%rip), %rcx       # 0xd5ca0
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rax
movb $0x1, 0x98(%rax)
movq -0x10(%rbp), %rdi
addq $0x98, %rdi
callq 0x16a360
movb $0x1, -0x2d(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4(%rax)
je 0xd5520
jmp 0xd5726
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xd5ce0
movb %al, -0x21(%rbp)
cmpb $0x0, -0x21(%rbp)
je 0xd5560
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x165170
movb %al, -0x2e(%rbp)
movq -0x20(%rbp), %rdi
movzbl -0x2e(%rbp), %esi
callq 0x178880
jmp 0xd550d
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xd5ce0
movb %al, -0x21(%rbp)
movzbl -0x21(%rbp), %eax
cmpl $0x0, %eax
jne 0xd55d5
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xd5ce0
movb %al, -0x22(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xd5ce0
movb %al, -0x23(%rbp)
movzbl -0x22(%rbp), %eax
shll %eax
movzbl -0x23(%rbp), %ecx
addl %ecx, %eax
addl $0x2, %eax
movl %eax, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x165170
movzbl %al, %ecx
movl $0xff, %eax
subl %ecx, %eax
movl %eax, -0x28(%rbp)
jmp 0xd569f
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x165170
movb %al, -0x2f(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x165170
movb %al, -0x30(%rbp)
movzbl -0x30(%rbp), %ecx
andl $0xf8, %ecx
shll $0x5, %ecx
movzbl -0x2f(%rbp), %eax
orl %eax, %ecx
movl $0x1fff, %eax           # imm = 0x1FFF
subl %ecx, %eax
movl %eax, -0x28(%rbp)
movzbl -0x30(%rbp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
jne 0xd568c
movb $0x3, -0x2d(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
addq $0x90, %rsi
callq 0x165170
movb %al, -0x31(%rbp)
movzbl -0x31(%rbp), %eax
cmpl $0x0, %eax
jne 0xd5670
movq -0x8(%rbp), %rdi
leaq 0xe5738(%rip), %rsi     # 0x1bad9f
movb $0x0, %al
callq 0x15b400
jmp 0xd56e6
movzbl -0x31(%rbp), %eax
cmpl $0x1, %eax
jne 0xd567e
jmp 0xd550d
movzbl -0x31(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xd568a
jmp 0xd569d
movb $0x2, -0x2d(%rbp)
movzbl -0x30(%rbp), %eax
andl $0x7, %eax
addl $0x2, %eax
movl %eax, -0x2c(%rbp)
jmp 0xd569f
movq -0x8(%rbp), %rax
cmpl $0x3, (%rax)
jl 0xd56c8
movq -0x8(%rbp), %rdi
movzbl -0x2d(%rbp), %edx
movl -0x28(%rbp), %ecx
addl $0x1, %ecx
movl -0x2c(%rbp), %r8d
leaq 0xe56e7(%rip), %rsi     # 0x1bada8
movb $0x0, %al
callq 0x15b400
movq -0x20(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x10(%rax), %esi
subl $0x1, %esi
subl -0x28(%rbp), %esi
movl -0x2c(%rbp), %edx
callq 0x1788e0
jmp 0xd550d
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rdi
callq 0x167c30
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x90(%rax), %rdx
subq -0x18(%rbp), %rdx
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
movq 0x18(%rax), %rcx
leaq 0xc9624(%rip), %rsi     # 0x19ed43
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x178950
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)