// File: ksherlock[P]wdc-utils/disassembler.cpp
// Function: disassembler::operator()(unsigned char)
void disassembler::operator()(uint8_t byte) {

	if (_st == 0 || !_code)
		check_labels();

	if (!_code) {
		_bytes[_st++] = byte;

		if (_inline_data && --_inline_data <= 0) {
			dump();
			_code = true;
			return;
		}

		if (_st == 4) dump();
		return;
	}

	_bytes[_st++] = byte;
	if (_st == 1) {
		_op = byte;
		_mode = modes[_op];

		// bit hack
		if (_traits & bit_hacks && _op == 0x2c) {
			if (_next_label == _pc + 1) {
				dump();
				return;
			}
		}

		if (_traits & pea_immediate && _op == 0xf4) _mode = 2 | mImmediate;
		_size = _mode & 0x0f;
		if (_mode & _flags & m_I) _size++;
		if (_mode & _flags & m_M) _size++;

		if (!_size) {
			print();

			if (branchlike(byte)) fputs("\n", stdout);
		}
		return;
	}
	unsigned shift = (_st - 2) * 8;
	_arg = _arg + (byte << shift);
	if (_st <= _size) return;

	uint8_t op = _op;
	uint32_t arg = _arg;

	if (_traits & track_rep_sep) {
		switch(_op) {
			case 0xc2: // REP
				_flags |= (_arg & 0x30);
				break;
			case 0xe2: // SEP
				_flags &= ~(_arg & 0x30);
				break;
		}
	}

	// all done... now print it.
	print();

	if (branchlike(op)) fputs("\n", stdout);

	// todo -- subscribe to before/after events...
	switch(op) {
		case 0xc2:
		case 0xe2:
		case 0x22:
		case 0x5c:
		case 0xdc:
			event(op, arg);
			break;
	}



}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpl $0x0, 0x8(%rax)
je 0xdf7a
movq -0x20(%rbp), %rax
testb $0x1, 0x28(%rax)
jne 0xdf83
movq -0x20(%rbp), %rdi
callq 0xd9b0
movq -0x20(%rbp), %rax
testb $0x1, 0x28(%rax)
jne 0xdfeb
movq -0x20(%rbp), %rax
movb -0x9(%rbp), %dl
movl 0x8(%rax), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x8(%rax)
movl %ecx, %ecx
movb %dl, 0x18(%rax,%rcx)
cmpl $0x0, 0x2c(%rax)
je 0xdfd3
movq -0x20(%rbp), %rcx
movl 0x2c(%rcx), %eax
addl $-0x1, %eax
movl %eax, 0x2c(%rcx)
cmpl $0x0, %eax
jg 0xdfd3
movq -0x20(%rbp), %rdi
callq 0xd490
movq -0x20(%rbp), %rax
movb $0x1, 0x28(%rax)
jmp 0xe223
movq -0x20(%rbp), %rax
cmpl $0x4, 0x8(%rax)
jne 0xdfe6
movq -0x20(%rbp), %rdi
callq 0xd490
jmp 0xe223
movq -0x20(%rbp), %rax
movb -0x9(%rbp), %dl
movl 0x8(%rax), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x8(%rax)
movl %ecx, %ecx
movb %dl, 0x18(%rax,%rcx)
cmpl $0x1, 0x8(%rax)
jne 0xe112
movq -0x20(%rbp), %rax
movb -0x9(%rbp), %cl
movb %cl, 0xc(%rax)
movzbl 0xc(%rax), %ecx
movl %ecx, %edx
leaq 0xd4ec(%rip), %rcx      # 0x1b510
movl (%rcx,%rdx,4), %ecx
movl %ecx, 0x14(%rax)
movl 0x34(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0xe063
movq -0x20(%rbp), %rax
movzbl 0xc(%rax), %eax
cmpl $0x2c, %eax
jne 0xe063
movq -0x20(%rbp), %rcx
movl 0x30(%rcx), %eax
movl 0x20(%rcx), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0xe061
movq -0x20(%rbp), %rdi
callq 0xd490
jmp 0xe223
jmp 0xe063
movq -0x20(%rbp), %rax
movl 0x34(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xe08c
movq -0x20(%rbp), %rax
movzbl 0xc(%rax), %eax
cmpl $0xf4, %eax
jne 0xe08c
movq -0x20(%rbp), %rax
movl $0x1002, 0x14(%rax)     # imm = 0x1002
movq -0x20(%rbp), %rcx
movl 0x14(%rcx), %eax
andl $0xf, %eax
movl %eax, 0x10(%rcx)
movl 0x14(%rcx), %eax
andl 0x1c(%rcx), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0xe0b4
movq -0x20(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rcx
movl 0x14(%rcx), %eax
andl 0x1c(%rcx), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0xe0d3
movq -0x20(%rbp), %rax
movl 0x10(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x10(%rax)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jne 0xe10d
movq -0x20(%rbp), %rdi
callq 0xe230
movzbl -0x9(%rbp), %edi
callq 0xe7b0
testb $0x1, %al
jne 0xe0f5
jmp 0xe10b
movq 0x16ec4(%rip), %rax     # 0x24fc0
movq (%rax), %rsi
leaq 0xd26d(%rip), %rdi      # 0x1b373
callq 0x32e0
jmp 0xe10d
jmp 0xe223
movq -0x20(%rbp), %rax
movl 0x8(%rax), %ecx
subl $0x2, %ecx
shll $0x3, %ecx
movl %ecx, -0x10(%rbp)
movl 0x24(%rax), %eax
movzbl -0x9(%rbp), %edx
movl -0x10(%rbp), %ecx
shll %cl, %edx
movq -0x20(%rbp), %rcx
addl %edx, %eax
movl %eax, 0x24(%rcx)
movl 0x8(%rcx), %eax
cmpl 0x10(%rcx), %eax
ja 0xe144
jmp 0xe223
movq -0x20(%rbp), %rax
movb 0xc(%rax), %cl
movb %cl, -0x11(%rbp)
movl 0x24(%rax), %ecx
movl %ecx, -0x18(%rbp)
movl 0x34(%rax), %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0xe1a6
movq -0x20(%rbp), %rax
movzbl 0xc(%rax), %eax
movl %eax, -0x24(%rbp)
subl $0xc2, %eax
je 0xe17f
jmp 0xe173
movl -0x24(%rbp), %eax
subl $0xe2, %eax
je 0xe191
jmp 0xe1a4
movq -0x20(%rbp), %rax
movl 0x24(%rax), %ecx
andl $0x30, %ecx
orl 0x1c(%rax), %ecx
movl %ecx, 0x1c(%rax)
jmp 0xe1a4
movq -0x20(%rbp), %rax
movl 0x24(%rax), %ecx
andl $0x30, %ecx
xorl $-0x1, %ecx
andl 0x1c(%rax), %ecx
movl %ecx, 0x1c(%rax)
jmp 0xe1a6
movq -0x20(%rbp), %rdi
callq 0xe230
movzbl -0x11(%rbp), %edi
callq 0xe7b0
testb $0x1, %al
jne 0xe1be
jmp 0xe1d4
movq 0x16dfb(%rip), %rax     # 0x24fc0
movq (%rax), %rsi
leaq 0xd1a4(%rip), %rdi      # 0x1b373
callq 0x32e0
movzbl -0x11(%rbp), %eax
movl %eax, -0x28(%rbp)
subl $0x22, %eax
je 0xe210
jmp 0xe1e2
movl -0x28(%rbp), %eax
subl $0x5c, %eax
je 0xe210
jmp 0xe1ec
movl -0x28(%rbp), %eax
subl $0xc2, %eax
je 0xe210
jmp 0xe1f8
movl -0x28(%rbp), %eax
subl $0xdc, %eax
je 0xe210
jmp 0xe204
movl -0x28(%rbp), %eax
subl $0xe2, %eax
jne 0xe223
jmp 0xe210
movq -0x20(%rbp), %rdi
movb -0x11(%rbp), %cl
movl -0x18(%rbp), %edx
movq (%rdi), %rax
movzbl %cl, %esi
callq *0x40(%rax)
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)