// File: /workspace/github_c_makefile_star2_O0/kisom[P]kam/vm.c
// Function: vm_step
int
vm_step(machine vm, uint8_t *prog, uint16_t prog_len)
{
	uint16_t	val;
	uint8_t		oper;

	if (NULL == vm) {
		fprintf(stderr, "[!] VM not initialised.\n");
		return VM_ERR;
	}

	if (vm->pc == prog_len)
		return VM_STOP;

	oper = prog[vm->pc];
	vm->pc++;
	switch (oper) {
	case INSTR_STOP:
		return VM_STOP;
	case INSTR_ADD:  /* fall through: store the operator in */
	case INSTR_SUB:  /* the op stack                        */
	case INSTR_DIV:
	case INSTR_MUL:
		push8(vm->opers, oper);
		break;
	case INSTR_IMM:
		/* detect wrap around */
		if ((prog_len - vm->pc) >= prog_len) {
			fprintf(stderr, "[!] PC overflow.\n");
			return VM_ERR;
		}
		/* ensure we have enough progspace left */
		if ((prog_len - vm->pc) < 2) {
			fprintf(stderr, "[!] Out of program space.\n");
			fprintf(stderr, "    %d bytes remain.\n", 
			    prog_len - vm->pc);
			return VM_ERR;
		}
		memcpy(&val, prog + vm->pc, sizeof(val));
		push16(vm->vals, val);
		vm->pc += 2; /* 2 bytes == 16 bits */
		break;
	case INSTR_DO:
		return eval(vm);
	default:
		fprintf(stderr, "[!] Unknown operator: %d.\n", oper);
		return VM_ERR;

	}
	return VM_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movw %dx, %ax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movw %ax, -0x1a(%rbp)
xorl %eax, %eax
cmpq -0x10(%rbp), %rax
jne 0x15f3
movq 0x2a22(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0xa50(%rip), %rsi       # 0x2030
movb $0x0, %al
callq 0x1080
movl $0x0, -0x4(%rbp)
jmp 0x177e
movq -0x10(%rbp), %rax
movzwl 0x10(%rax), %eax
movzwl -0x1a(%rbp), %ecx
cmpl %ecx, %eax
jne 0x160f
movl $0x2, -0x4(%rbp)
jmp 0x177e
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
movb (%rax,%rcx), %al
movb %al, -0x1d(%rbp)
movq -0x10(%rbp), %rax
movw 0x10(%rax), %cx
incw %cx
movw %cx, 0x10(%rax)
movzbl -0x1d(%rbp), %eax
movq %rax, -0x28(%rbp)
subq $0x6, %rax
ja 0x1752
movq -0x28(%rbp), %rax
leaq 0x9b7(%rip), %rcx       # 0x2004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x2, -0x4(%rbp)
jmp 0x177e
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
movzbl -0x1d(%rbp), %esi
callq 0x1210
jmp 0x1777
movzwl -0x1a(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
subl %ecx, %eax
movzwl -0x1a(%rbp), %ecx
cmpl %ecx, %eax
jl 0x16b2
movq 0x2963(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0x9aa(%rip), %rsi       # 0x2049
movb $0x0, %al
callq 0x1080
movl $0x0, -0x4(%rbp)
jmp 0x177e
movzwl -0x1a(%rbp), %eax
movq -0x10(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
subl %ecx, %eax
cmpl $0x2, %eax
jge 0x170c
movq 0x292c(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
leaq 0x985(%rip), %rsi       # 0x205b
movb $0x0, %al
callq 0x1080
movq 0x2914(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movzwl -0x1a(%rbp), %edx
movq -0x10(%rbp), %rax
movzwl 0x10(%rax), %eax
subl %eax, %edx
leaq 0x97a(%rip), %rsi       # 0x2076
movb $0x0, %al
callq 0x1080
movl $0x0, -0x4(%rbp)
jmp 0x177e
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
movslq %ecx, %rcx
movw (%rax,%rcx), %ax
movw %ax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rdi
movzwl -0x1c(%rbp), %esi
callq 0x1390
movq -0x10(%rbp), %rax
movzwl 0x10(%rax), %ecx
addl $0x2, %ecx
movw %cx, 0x10(%rax)
jmp 0x1777
movq -0x10(%rbp), %rdi
callq 0x1790
movl %eax, -0x4(%rbp)
jmp 0x177e
movq 0x289f(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
movzbl -0x1d(%rbp), %edx
leaq 0x925(%rip), %rsi       # 0x208c
movb $0x0, %al
callq 0x1080
movl $0x0, -0x4(%rbp)
jmp 0x177e
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)