// File: /workspace/github_cpp_makefile_star2_O3/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, %rbx
leaq 0x88(%rdi), %rax
movq %rax, (%rsp)
movl 0x7c(%rdi), %eax
leaq 0x17d6f9(%rip), %r15    # 0x582010
movl $0xffff, %r13d          # imm = 0xFFFF
leaq 0x17d70c(%rip), %r14    # 0x582030
xorl %r12d, %r12d
cmpl $0x3, %eax
ja 0x404be7
movl %eax, %eax
movslq (%r15,%rax,4), %rax
addq %r15, %rax
jmpq *%rax
movzwl 0x2(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
movw %ax, 0x80(%rbx)
addl $-0x7f, %eax
cmpw $-0x5e, %ax
jae 0x4049ce
jmp 0x404bd1
movzwl 0x2(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
leal -0x21(%rax), %ecx
cmpw $0x60, %cx
jae 0x404bca
movzwl 0x2(%rbx), %esi
movzwl %ax, %eax
addl $-0x21, %eax
leaq 0x17d9ba(%rip), %rcx    # 0x582340
movsbl (%rax,%rcx), %eax
movzwl %ax, %edx
movq %rbx, %rdi
callq 0x404860
jmp 0x4049ce
movzwl 0x2(%rbx), %eax
movzwl 0x4(%rbx), %ecx
movzwl %ax, %edx
movl $0x1958, %edi           # imm = 0x1958
leal (%rax,%rdi), %esi
incl %eax
movl $0xe6a8, %r8d           # imm = 0xE6A8
cmpl %r8d, %edx
cmovael %esi, %eax
movw %ax, 0x2(%rbx)
movzwl %cx, %eax
leal (%rcx,%rdi), %edx
incl %ecx
cmpl %r8d, %eax
cmovael %edx, %ecx
movw %cx, 0x4(%rbx)
movl 0x7c(%rbx), %eax
leal 0x1(%rax), %ecx
leal 0x4(%rax), %edx
testl %ecx, %ecx
cmovnsl %ecx, %edx
andl $-0x4, %edx
negl %edx
addl %edx, %eax
incl %eax
movl %eax, 0x7c(%rbx)
incq %r12
cmpq $0x5f5e100, %r12        # imm = 0x5F5E100
jne 0x404927
jmp 0x404bc3
movzwl 0x80(%rbx), %eax
movzwl 0x2(%rbx), %ecx
leal (%rax,%rcx), %edx
addl %ecx, %eax
addl $-0x21, %eax
cltq
imulq $-0x51b3bea3, %rax, %rcx # imm = 0xAE4C415D
shrq $0x20, %rcx
addl %edx, %ecx
addl $-0x21, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
shrl $0x6, %ecx
addl %edx, %ecx
imull $0x5e, %ecx, %ecx
subl %ecx, %eax
movzwl %ax, %eax
cmpl $0x2f, %eax
jg 0x404ae8
cmpl $0x6, %eax
je 0x404b56
cmpl $0x7, %eax
je 0x404b93
cmpl $0x1d, %eax
jne 0x4049ce
movzwl (%rbx), %ebp
movzwl 0x4(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
movl %eax, %ecx
xorl %r8d, %r8d
xorl %edi, %edi
leaq 0x17d5ab(%rip), %r11    # 0x582020
movzwl (%r8,%r11), %r9d
movl %ecx, %eax
xorl %edx, %edx
divw %r9w
movl %eax, %esi
movzwl %ax, %eax
imull $0xe38f, %eax, %eax     # imm = 0xE38F
shrl $0x13, %eax
leal (%rax,%rax,8), %r10d
movl %ebp, %eax
xorl %edx, %edx
divw %r9w
subl %r10d, %esi
movzwl %ax, %edx
imull $0xe38f, %edx, %edx     # imm = 0xE38F
andl %r13d, %esi
shrl $0x13, %edx
leal (%rdx,%rdx,8), %edx
leaq (%rsi,%rsi,8), %rsi
subl %edx, %eax
leaq (%r14,%rsi,2), %rdx
andl %r13d, %eax
imulw (%rdx,%rax,2), %r9w
addl %r9d, %edi
addq $0x2, %r8
cmpq $0xa, %r8
jne 0x404a75
movw %di, (%rbx)
movzwl 0x4(%rbx), %esi
movzwl %di, %edx
movq %rbx, %rdi
callq 0x404860
jmp 0x4049ce
xorl %ebp, %ebp
cmpl $0x41, %eax
jg 0x404b0a
jne 0x404ba8
movzwl 0x4(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
movw %ax, 0x2(%rbx)
jmp 0x4049ce
cmpl $0x42, %eax
jne 0x404bb3
movl $0x0, 0x14(%rbx)
movq 0x90(%rbx), %rcx
movl $0x4, %ebp
cmpq 0x1eda33(%rip), %rcx    # 0x5f2560
jae 0x404bd6
movb (%rbx), %al
movq 0x1eda1c(%rip), %rdx    # 0x5f2558
cmpb %al, (%rdx,%rcx)
jne 0x404bd6
movsbl %al, %esi
movq (%rsp), %rdi
callq 0x480b50
jmp 0x4049ce
movzwl 0x4(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
movzwl %ax, %ecx
imull $0xaaab, %ecx, %ecx     # imm = 0xAAAB
shrl $0x11, %ecx
imull $0x4ce3, %eax, %eax     # imm = 0x4CE3
imull $0x1958, %ecx, %ecx     # imm = 0x1958
addl %eax, %ecx
movw %cx, (%rbx)
movzwl 0x4(%rbx), %esi
movzwl %cx, %edx
movq %rbx, %rdi
callq 0x404860
jmp 0x4049ce
movzwl 0x4(%rbx), %esi
movq %rbx, %rdi
callq 0x404628
movw %ax, 0x4(%rbx)
jmp 0x4049ce
cmpl $0x30, %eax
jne 0x4049ce
jmp 0x404bd6
cmpl $0x54, %eax
jne 0x4049ce
movl $0x2, %ebp
jmp 0x404bd6
movl $0x3, %ebp
jmp 0x404bd6
movl $0x5, %ebp
jmp 0x404bd6
movl $0x1, %ebp
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq $0x5f3420, %rdi         # imm = 0x5F3420
leaq 0x17d54b(%rip), %rsi    # 0x582140
movl $0x32, %edx
callq 0x470090
movl 0x7c(%rbx), %esi
movq $0x5f3420, %rdi         # imm = 0x5F3420
callq 0x470960
movq %rax, %rdi
callq 0x46fea0
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x4ccac0
jmp 0x404c28
jmp 0x404c28
jmp 0x404c28
jmp 0x404c28
movq %rax, %rdi
cmpl $0x1, %edx
jne 0x404c4c
callq 0x406650
movl (%rax), %eax
addl $-0x2a, %eax
andl $-0x3, %eax
xorl %ebp, %ebp
cmpl $0x1, %eax
adcl $0x5, %ebp
callq 0x4066c0
jmp 0x404bd6
callq 0x4b1210
nop