// File: /workspace/github_cpp_makefile_star2_O3/jmbjorndalen[P]Malbolge-gen/mbolge-gen.cpp
// Function: MBSearch::getMem(unsigned short)
unsigned short MBSearch::getMem(unsigned short addr)
{
    if (addr >= MAX_TRIT)
    { 
	//std::cerr << "MBSearch::getMem called with addr " << addr << " with is outside legal bounds\n";
	throw ILLEGAL_ADDR_EXCEPTION; // program made an illegal reference, which will not fare well with the original interpreter, so abort this branch
    }
    if (addr >= maxAllowedProgLen) 
	throw MAX_APLEN_EXCEPTION;
    
    if (addr > highestAddrRead)
	highestAddrRead = addr; 
    
    MBMemory::iterator pos = mem.find(addr); 
    if (pos != mem.end())
	return pos->second;  // already have it

    // Reading a new memory location that has never been visited before. 
    // First, check whether we have branched out too deeply before omitting chars
    ++odepth; 
    if (odepth > MAX_OSEARCH)
	throw BRANCH_DEPTH_EXCEPTION; 

    // Simply fill in the first possible OP, then store this object on the stack, allowing the main loop to 
    // pick it up again and modify it later (restarting the object with the next possible instruction). 
    curNewMem = addr;         // keep track of addr, so main loop can modify this instruction
    curNewOP  = 0;            // we're currently using the first one
    orig[addr] = mem[addr]  = encode_op(MalbolgeOps[curNewOP], addr);
    ++nFetches;

    // Store a copy of this one on the stack
    globalStack.push(new MBSearch(*this));     // default copy constructor is ok

    return mem[addr];
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
cmpl $0xe6a9, %esi           # imm = 0xE6A9
jae 0x4047e6
movl %esi, %ebx
cmpl %esi, 0x1ebae6(%rip)    # 0x5f0130
jle 0x4047f8
movq %rdi, %r14
addq $0x78, %rdi
cmpl %ebx, 0x78(%r14)
jge 0x40465f
movl %ebx, (%rdi)
movq 0x28(%r14), %rcx
testq %rcx, %rcx
je 0x404694
leaq 0x20(%r14), %rdx
movq %rdx, %rax
xorl %esi, %esi
cmpl %ebx, 0x20(%rcx)
setb %sil
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rsi,8), %rcx
testq %rcx, %rcx
jne 0x40466f
cmpq %rdx, %rax
je 0x404694
cmpl %ebx, 0x20(%rax)
jbe 0x4047e1
movq %rdi, 0x18(%rsp)
movl 0x14(%r14), %eax
leal 0x1(%rax), %ecx
movl %ecx, 0x14(%r14)
cmpl $0xa, %eax
jge 0x40480a
leaq 0x18(%r14), %r15
movl %ebx, 0xc(%r14)
movl $0x0, 0x10(%r14)
movzwl 0x1eba7c(%rip), %eax    # 0x5f0140
subl %ebx, %eax
cltq
imulq $-0x51b3bea3, %rax, %rcx # imm = 0xAE4C415D
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
sarl $0x6, %ecx
addl %edx, %ecx
imull $0x5e, %ecx, %ecx
movl %eax, %edx
subl %ecx, %edx
negl %ecx
testl %edx, %edx
leal 0x5e(%rax,%rcx), %eax
cmovnsl %edx, %eax
addl $0x21, %eax
movzwl %ax, %ebp
leaq 0x8(%rsp), %rsi
movl %ebx, (%rsi)
movq %r15, %rdi
callq 0x405800
movl %ebp, (%rax)
leaq 0x48(%r14), %r13
leaq 0x24(%rsp), %rsi
movl %ebx, (%rsi)
movq %r13, %rdi
callq 0x405800
movl %ebp, (%rax)
incl 0x8(%r14)
movl $0xa8, %edi
callq 0x407640
movq %rax, %r12
movups (%r14), %xmm0
movups %xmm0, (%rax)
movq 0x10(%r14), %rax
movq %rax, 0x10(%r12)
leaq 0x18(%r12), %rdi
movq %rdi, 0x10(%rsp)
movq %r15, %rsi
callq 0x4058c8
leaq 0x48(%r12), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0x4058c8
movq 0x18(%rsp), %rcx
movzwl 0x8(%rcx), %eax
movw %ax, 0x80(%r12)
movq (%rcx), %rax
movq %rax, 0x78(%r12)
leaq 0x88(%r12), %rdi
movq %r12, %rax
addq $0x98, %rax
movq %rax, 0x88(%r12)
movq 0x88(%r14), %rsi
movq 0x90(%r14), %rdx
addq %rsi, %rdx
callq 0x405a9c
leaq 0x8(%rsp), %r14
movq %r12, (%r14)
leaq 0x1eddc0(%rip), %rdi    # 0x5f2578
movq %r14, %rsi
callq 0x405f56
movl %ebx, (%r14)
leaq 0x8(%rsp), %rsi
movq %r15, %rdi
callq 0x405800
movl (%rax), %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl 0x24(%rax), %eax
jmp 0x4047d2
movl $0x4, %edi
callq 0x4064f0
movl $0x2b, (%rax)
jmp 0x40481a
movl $0x4, %edi
callq 0x4064f0
movl $0x2c, (%rax)
jmp 0x40481a
movl $0x4, %edi
callq 0x4064f0
movl $0x2a, (%rax)
leaq 0x1e418f(%rip), %rsi    # 0x5e89b0
movq %rax, %rdi
xorl %edx, %edx
callq 0x407540
movq %rax, %rbx
movq %rbp, %rdi
callq 0x405b32
jmp 0x40483b
movq %rax, %rbx
movq 0x10(%rsp), %rdi
callq 0x405b32
jmp 0x40484a
movq %rax, %rbx
movl $0xa8, %esi
movq %r12, %rdi
callq 0x406210
movq %rbx, %rdi
callq 0x4b1210
nop