// File: /workspace/github_cpp_makefile_star2_O2/jmbjorndalen[P]Malbolge-gen/mbolge-gen.cpp
// Function: MBSearch::doExec()
int MBSearch::doExec()
{
    const long long MAX_ITERS = 100000000LL; 
    long long iters; 
    try
    { 
	for (iters = 0; iters < MAX_ITERS; iters++) // Guard againt infinite loops
	{ 
	    switch(iStage) { 
	    case STAGE_IFETCH:    // instruction fetch
		 instr = getMem(Rc); 
		// Check for infinity: trying to execute values outside the 94-range causes an infinite loop!
		if (instr < 33 || instr > 126) 
		    return RES_INFINITE_LOOP; 
		break; 
	    case STAGE_EXEC:      // execute given instruction
		// Decode op to NOP or one of the 8 ops. 
		switch (decode_op(instr, Rc))
		{
		case OP_READ_DATA:  // read data register from current 
		    Rd = getMem(Rd);
		    break;
		case OP_READ_IP:  // jump to addr 
		    Rc = getMem(Rd);
		    break;
		case OP_ROT_RIGHT:  // rotate right 1, lstrit=> mstrit (3**9 = 19683)
		{
		    unsigned short t = getMem(Rd); 
		    Ra = t / 3 + t % 3 * 19683;
		    storeMem(Rd, Ra);
		    break; 
		}
		case OP_TERNARY:  // run ternary operator on two values
		    Ra = op(Ra, getMem(Rd));
		    storeMem(Rd, Ra);
		    break;
		case OP_WRITE:  // output accumulator as a character
		{
		    // Checks whether this is a 'good' character, otherwise abort!
		    odepth = 0; 
		    char c = (char) Ra; 
		    if ((output.length() >= TARGET.length()) ||  // too long string
			(c != TARGET[output.length()]))          // wrong character
			return RES_WRITE_MISMATCH; 
		    output += c; 
		    break;
		}
		case OP_READ:  // We don't allow input from stdin in the program
		    return RES_TRIED_INPUT; 
		case OP_TERMINATE:  // terminate program
		    return RES_OK;
		case OP_NOP:
		default: // Unspecified operatins correspond to NOPs in the original interpreter
		    break;  
		}
		break; 
	    case STAGE_MODMEM:   { // modify location of memory that the Rc register currently points at
		// Modify op at position. Note that all chars in xlat2 are in the legal range for ops: 33..126
		// So, an OP will always be translated into an OP (either a NOP or the other 8 ops)
		int addr = getMem(Rc); 
		if (addr < 33 || (addr > (95+33)))
		{ 
		    // Pruning search paths that result in accesses out of bounds for xlat2
		    // NB: This happens very often when we search for programs, so we need to explicitly prune these
		    // paths as they will not execute correctly if we try them with the interpreter.
		    return RES_ERROR; 
		}
		storeMem(Rc, xlat2[addr - 33]);	
		break; 
	    }
	    case STAGE_MODINC:    // modulo increment instruction and data pointer
		Rc = modInc(Rc, MAX_TRIT); 
		Rd = modInc(Rd, MAX_TRIT); 
		break; 
	    default:
		std::cerr << "ERROR, interpreter interpreter with illegal stage " << iStage << std::endl; 
		exit(-1);
	    } 
	    iStage = (InterpreterStage) modInc(iStage, STAGE_NUMSTAGES); 
	}
    }
    catch (MB_Exception e)
    {
	switch (e) { 
	case BRANCH_DEPTH_EXCEPTION:
	case MAX_APLEN_EXCEPTION:
	    return RES_BRANCH_DEPTH;
	default:
	    return RES_ERROR;
	}
    }
    return RES_MAX_ITERS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %r14
leaq 0x88(%rdi), %rax
movq %rax, (%rsp)
leaq 0x17e6da(%rip), %r13    # 0x583010
movw $0x9, %r15w
leaq 0x17e6ee(%rip), %r12    # 0x583030
xorl %ebx, %ebx
cmpq $0x5f5e100, %rbx        # imm = 0x5F5E100
je 0x404b97
movl 0x7c(%r14), %eax
cmpq $0x3, %rax
ja 0x404bbf
movslq (%r13,%rax,4), %rax
addq %r13, %rax
jmpq *%rax
movzwl 0x2(%r14), %esi
movq %r14, %rdi
callq 0x404734
movw %ax, 0x80(%r14)
addl $-0x7f, %eax
cmpw $-0x5e, %ax
jae 0x4049fe
jmp 0x404baf
movzwl 0x2(%r14), %esi
movq %r14, %rdi
callq 0x404734
leal -0x21(%rax), %ecx
cmpw $0x60, %cx
jae 0x404bab
movzwl 0x2(%r14), %esi
movzwl %ax, %eax
addl $-0x21, %eax
leaq 0x17e968(%rip), %rcx    # 0x583320
movsbl (%rax,%rcx), %eax
movzwl %ax, %edx
movq %r14, %rdi
callq 0x404888
jmp 0x4049fe
movzwl 0x2(%r14), %eax
movl $0x1958, %esi           # imm = 0x1958
leal (%rax,%rsi), %ecx
leal 0x1(%rax), %edx
movw $0xe6a8, %di            # imm = 0xE6A8
cmpw %di, %ax
cmovael %ecx, %edx
movzwl 0x4(%r14), %eax
movw %dx, 0x2(%r14)
leal (%rax,%rsi), %ecx
leal 0x1(%rax), %edx
cmpw %di, %ax
cmovael %ecx, %edx
movw %dx, 0x4(%r14)
movl 0x7c(%r14), %eax
incl %eax
cltd
pushq $0x4
popq %rcx
idivl %ecx
movl %edx, 0x7c(%r14)
incq %rbx
jmp 0x404944
movzwl 0x80(%r14), %eax
movzwl 0x2(%r14), %ecx
addl %ecx, %eax
addl $-0x21, %eax
cltd
pushq $0x5e
popq %rcx
idivl %ecx
cmpw $0x6, %dx
je 0x404b3f
movzwl %dx, %eax
cmpl $0x7, %eax
je 0x404ad4
cmpl $0x1d, %eax
je 0x404a6e
cmpl $0x41, %eax
je 0x404b28
cmpl $0x42, %eax
je 0x404aeb
cmpl $0x30, %eax
je 0x404bbb
cmpl $0x54, %eax
jne 0x4049fe
jmp 0x404bb7
movzwl (%r14), %ebp
movzwl 0x4(%r14), %esi
movq %r14, %rdi
callq 0x404734
movl %eax, %ecx
xorl %esi, %esi
xorl %edi, %edi
cmpq $0xa, %rsi
je 0x404b7e
leaq 0x17e58a(%rip), %rax    # 0x583020
movzwl (%rsi,%rax), %r8d
movl %ecx, %eax
xorl %edx, %edx
divw %r8w
xorl %edx, %edx
divw %r15w
movzwl %dx, %r9d
movl %ebp, %eax
xorl %edx, %edx
divw %r8w
xorl %edx, %edx
divw %r15w
imulq $0x12, %r9, %rax
addq %r12, %rax
movzwl %dx, %edx
imulw (%rax,%rdx,2), %r8w
addl %r8d, %edi
addq $0x2, %rsi
jmp 0x404a85
movzwl 0x4(%r14), %esi
movq %r14, %rdi
callq 0x404734
movw %ax, 0x4(%r14)
jmp 0x4049fe
andl $0x0, 0x14(%r14)
movq 0x90(%r14), %rcx
cmpq 0x1efa62(%rip), %rcx    # 0x5f4560
jae 0x404bb3
movb (%r14), %al
movq 0x1efa4a(%rip), %rdx    # 0x5f4558
cmpb %al, (%rdx,%rcx)
jne 0x404bb3
movsbl %al, %esi
movq (%rsp), %rdi
callq 0x480820
jmp 0x4049fe
movzwl 0x4(%r14), %esi
movq %r14, %rdi
callq 0x404734
movw %ax, 0x2(%r14)
jmp 0x4049fe
movzwl 0x4(%r14), %esi
movq %r14, %rdi
callq 0x404734
movl %eax, %ecx
xorl %edx, %edx
movw $0x3, %si
divw %si
imull $0x4ce3, %ecx, %ecx     # imm = 0x4CE3
imull $0x1958, %eax, %eax     # imm = 0x1958
addl %ecx, %eax
movw %ax, (%r14)
movzwl 0x4(%r14), %esi
movzwl %ax, %edx
movq %r14, %rdi
callq 0x404888
jmp 0x4049fe
movw %di, (%r14)
movzwl 0x4(%r14), %esi
movzwl %di, %edx
movq %r14, %rdi
callq 0x404888
jmp 0x4049fe
pushq $0x3
popq %rbx
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $0x5
jmp 0x404b99
pushq $0x1
jmp 0x404b99
pushq $0x4
jmp 0x404b99
pushq $0x2
jmp 0x404b99
xorl %ebx, %ebx
jmp 0x404b9a
movq $0x5f5420, %rdi         # imm = 0x5F5420
leaq 0x17e555(%rip), %rsi    # 0x583122
callq 0x470290
movl 0x7c(%r14), %esi
movq %rax, %rdi
callq 0x470630
movq %rax, %rdi
callq 0x46fb70
pushq $-0x1
popq %rdi
callq 0x4cd2f0
jmp 0x404bf6
jmp 0x404bf6
jmp 0x404bf6
jmp 0x404bf6
movq %rax, %rdi
cmpl $0x1, %edx
jne 0x404c1a
callq 0x406320
movl (%rax), %eax
addl $-0x2a, %eax
andl $-0x3, %eax
xorl %ebx, %ebx
cmpl $0x1, %eax
adcl $0x5, %ebx
callq 0x406390
jmp 0x404b9a
callq 0x4b1a40
nop