// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x145a
movq %rdi, %rbx
movzwl 0x10(%rdi), %ecx
pushq $0x2
popq %rbp
cmpw %dx, %cx
je 0x13d8
movzbl (%rsi,%rcx), %eax
incl %ecx
movw %cx, 0x10(%rbx)
cmpq $0x6, %rax
ja 0x14aa
leaq 0xc44(%rip), %rdi       # 0x2004
movslq (%rdi,%rax,4), %r8
addq %rdi, %r8
jmpq *%r8
movq 0x8(%rbx), %rdi
movl %eax, %esi
callq 0x11f0
pushq $0x1
popq %rbp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
testw %cx, %cx
je 0x14c1
movzwl %dx, %r14d
movzwl %cx, %eax
movl %r14d, %ecx
subl %eax, %ecx
cmpl $0x1, %ecx
jle 0x14d6
movzwl (%rsi,%rax), %esi
movq (%rbx), %rdi
callq 0x1282
addw $0x2, 0x10(%rbx)
jmp 0x13d5
movq (%rbx), %rdi
callq 0x12b0
movl %eax, %ebp
movq (%rbx), %rdi
callq 0x12b0
movl %eax, %r14d
movq 0x8(%rbx), %rdi
callq 0x121e
movzbl %al, %eax
decl %eax
cmpl $0x3, %eax
ja 0x1514
leaq 0xbd7(%rip), %rcx       # 0x2020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%rbx), %rdi
addl %ebp, %r14d
jmp 0x149c
movq 0x2b97(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0xbc5(%rip), %rdi       # 0x2030
pushq $0x18
popq %rsi
pushq $0x1
popq %rdx
callq 0x10d0
xorl %ebp, %ebp
jmp 0x13d8
movq (%rbx), %rdi
imull %ebp, %r14d
jmp 0x149c
movq (%rbx), %rdi
movl %r14d, %eax
xorl %edx, %edx
divw %bp
movzwl %ax, %esi
jmp 0x14a0
movq (%rbx), %rdi
subl %ebp, %r14d
movzwl %r14w, %esi
callq 0x1282
jmp 0x13d5
movq 0x2b47(%rip), %rcx      # 0x3ff8
movq (%rcx), %rdi
leaq 0xbd1(%rip), %rsi       # 0x208c
xorl %ebp, %ebp
movl %eax, %edx
jmp 0x1508
movq 0x2b30(%rip), %rax      # 0x3ff8
movq (%rax), %rcx
leaq 0xb77(%rip), %rdi       # 0x2049
pushq $0x11
jmp 0x146d
movq 0x2b1b(%rip), %r15      # 0x3ff8
movq (%r15), %rcx
leaq 0xb74(%rip), %rdi       # 0x205b
pushq $0x1a
popq %rsi
pushq $0x1
popq %rdx
callq 0x10d0
movq (%r15), %rdi
movzwl 0x10(%rbx), %eax
subl %eax, %r14d
leaq 0xb73(%rip), %rsi       # 0x2076
xorl %ebp, %ebp
movl %r14d, %edx
xorl %eax, %eax
callq 0x1090
jmp 0x13d8
callq 0x1040