// File: Merulo[P]CompilerJFTT/src/Register/RegisterBlock.cpp
// Function: RegisterBlock::getRegister(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Block&, std::vector<std::reference_wrapper<Register>, std::allocator<std::reference_wrapper<Register>>>, bool, bool)
Register& RegisterBlock::getRegister(std::string name, 
    Block& b, std::vector<std::reference_wrapper<Register>> usedRegisters, 
    bool changeValue, bool load)
{
    if (changeValue)
    {
        storeSameTable(name , b);
    }
    for(auto& reg : _registers)
    {
        if (std::find_if(usedRegisters.begin(), usedRegisters.end(), [reg](auto i)
                {
                    return i.get() == reg;
                }) != usedRegisters.end())
        {      
            continue;
        }         
        if (reg.variableName == name)
        {
            return reg;
        }
    }
    for(auto& reg : _registers)
    {
        if (reg.state == RegisterState::UNKNOWN)
        {
            if (load)
            {
                loadFromMemory(b, name, reg, _addressRegister);
            }
            return reg;
        }
    }

    auto & reg = _registers[_currentRegister];
    _currentRegister++;
    if (_currentRegister == _registers.size())
    {
        _currentRegister = 0;
    }

    if (reg.state == RegisterState::CONST)
    {
        return getRegister(name, b, usedRegisters, changeValue, load);
    }

    if (std::find_if(usedRegisters.begin(), usedRegisters.end(), [reg](auto i)
            {
                return i.get() == reg;
            }) == usedRegisters.end())
    {
        saveToMemory(b, reg, _addressRegister);
        if (load)
        {
            loadFromMemory(b, name, reg, _addressRegister);
        }        
        return reg;
    }    

    return getRegister(name, b, usedRegisters, changeValue, load); 
}

// Assembly:
subq $0x2f8, %rsp            # imm = 0x2F8
movl %r8d, 0x8c(%rsp)
movq %rcx, %rax
movl 0x8c(%rsp), %ecx
movq %rax, 0x90(%rsp)
movq %rdx, %rax
movq 0x90(%rsp), %rdx
movq %rax, 0x98(%rsp)
movq %rsi, %rax
movq 0x98(%rsp), %rsi
movq %rax, 0xa0(%rsp)
movq %rdi, %r8
movq 0xa0(%rsp), %rdi
movb %r9b, %al
movq %r8, 0x2e8(%rsp)
movq %rdi, 0x2e0(%rsp)
movq %rsi, 0x2d8(%rsp)
movq %rdx, 0x2d0(%rsp)
andb $0x1, %cl
movb %cl, 0x2cf(%rsp)
andb $0x1, %al
movb %al, 0x2ce(%rsp)
movq 0x2e8(%rsp), %rax
movq %rax, 0xa8(%rsp)
testb $0x1, 0x2cf(%rsp)
je 0x7bd3
movq 0xa0(%rsp), %rsi
leaq 0x2a8(%rsp), %rdi
movq %rdi, 0x80(%rsp)
callq 0x4180
movq 0xa8(%rsp), %rdi
movq 0x80(%rsp), %rsi
movq 0x2d8(%rsp), %rdx
callq 0x82d0
jmp 0x7b9e
leaq 0x2a8(%rsp), %rdi
callq 0x46e8
jmp 0x7bd3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0x2a8(%rsp), %rdi
callq 0x46e8
jmp 0x82be
movq 0xa8(%rsp), %rax
addq $0x68, %rax
movq %rax, 0x290(%rsp)
movq 0x290(%rsp), %rdi
callq 0xd710
movq %rax, 0x288(%rsp)
movq 0x290(%rsp), %rdi
callq 0xd740
movq %rax, 0x280(%rsp)
leaq 0x288(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0xd770
testb $0x1, %al
jne 0x7c2f
jmp 0x7d6b
leaq 0x288(%rsp), %rdi
callq 0xd7b0
movq 0x90(%rsp), %rdi
movq %rax, 0x278(%rsp)
callq 0xd820
movq 0x90(%rsp), %rdi
movq %rax, 0x268(%rsp)
callq 0xd850
movq %rax, 0x260(%rsp)
movq 0x278(%rsp), %rsi
leaq 0x208(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0xd080
movq 0x70(%rsp), %rdx
movq 0x268(%rsp), %rdi
movq 0x260(%rsp), %rsi
callq 0x85f0
movq %rax, 0x78(%rsp)
jmp 0x7ca9
movq 0x90(%rsp), %rdi
movq 0x78(%rsp), %rax
movq %rax, 0x270(%rsp)
callq 0xd850
movq %rax, 0x200(%rsp)
leaq 0x270(%rsp), %rdi
leaq 0x200(%rsp), %rsi
callq 0xd7e0
movb %al, 0x6f(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x8700
movb 0x6f(%rsp), %al
testb $0x1, %al
jne 0x7cfb
jmp 0x7d23
jmp 0x7d59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0x208(%rsp), %rdi
callq 0x8700
jmp 0x82be
movq 0xa0(%rsp), %rsi
movq 0x278(%rsp), %rdi
addq $0x30, %rdi
callq 0xd2c0
testb $0x1, %al
jne 0x7d42
jmp 0x7d57
movq 0x278(%rsp), %rax
movq %rax, 0x2f0(%rsp)
jmp 0x82ae
jmp 0x7d59
leaq 0x288(%rsp), %rdi
callq 0xd7c0
jmp 0x7c11
movq 0xa8(%rsp), %rax
addq $0x68, %rax
movq %rax, 0x1f8(%rsp)
movq 0x1f8(%rsp), %rdi
callq 0xd710
movq %rax, 0x1f0(%rsp)
movq 0x1f8(%rsp), %rdi
callq 0xd740
movq %rax, 0x1e8(%rsp)
leaq 0x1f0(%rsp), %rdi
leaq 0x1e8(%rsp), %rsi
callq 0xd770
testb $0x1, %al
jne 0x7dc7
jmp 0x7ea8
leaq 0x1f0(%rsp), %rdi
callq 0xd7b0
movq %rax, 0x1e0(%rsp)
movq 0x1e0(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x7e94
testb $0x1, 0x2ce(%rsp)
je 0x7e7f
movq 0xa0(%rsp), %rsi
movq 0x2d8(%rsp), %rax
movq %rax, 0x58(%rsp)
leaq 0x1c0(%rsp), %rdi
movq %rdi, 0x60(%rsp)
callq 0x4180
movq 0xa8(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x60(%rsp), %rdx
movq 0x1e0(%rsp), %rcx
movq %rdi, %r8
addq $0x10, %r8
callq 0x6310
jmp 0x7e4a
leaq 0x1c0(%rsp), %rdi
callq 0x46e8
jmp 0x7e7f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0x1c0(%rsp), %rdi
callq 0x46e8
jmp 0x82be
movq 0x1e0(%rsp), %rax
movq %rax, 0x2f0(%rsp)
jmp 0x82ae
jmp 0x7e96
leaq 0x1f0(%rsp), %rdi
callq 0xd7c0
jmp 0x7da9
movq 0xa8(%rsp), %rax
movq %rax, %rdi
addq $0x68, %rdi
movl 0x80(%rax), %eax
movl %eax, %esi
callq 0xd360
movq 0xa8(%rsp), %rdi
movq %rax, 0x1b8(%rsp)
movl 0x80(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x80(%rdi)
movl 0x80(%rdi), %eax
movq %rax, 0x50(%rsp)
addq $0x68, %rdi
callq 0xd2a0
movq %rax, %rcx
movq 0x50(%rsp), %rax
cmpq %rcx, %rax
jne 0x7f16
movq 0xa8(%rsp), %rax
movl $0x0, 0x80(%rax)
movq 0x1b8(%rsp), %rax
cmpl $0x2, (%rax)
jne 0x8018
movq 0xa0(%rsp), %rsi
leaq 0x198(%rsp), %rdi
callq 0x4180
movq 0x90(%rsp), %rsi
movq 0x2d8(%rsp), %rax
movq %rax, 0x48(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xd8c0
jmp 0x7f60
movq 0x48(%rsp), %rdx
movq 0xa8(%rsp), %rdi
movzbl 0x2ce(%rsp), %r9d
movzbl 0x2cf(%rsp), %r8d
andl $0x1, %r8d
andl $0x1, %r9d
leaq 0x198(%rsp), %rsi
leaq 0x180(%rsp), %rcx
callq 0x7ac0
movq %rax, 0x40(%rsp)
jmp 0x7fa3
movq 0x40(%rsp), %rax
movq %rax, 0x2f0(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xd9c0
leaq 0x198(%rsp), %rdi
callq 0x46e8
jmp 0x82ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
jmp 0x8006
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0x180(%rsp), %rdi
callq 0xd9c0
leaq 0x198(%rsp), %rdi
callq 0x46e8
jmp 0x82be
movq 0x90(%rsp), %rdi
callq 0xd820
movq 0x90(%rsp), %rdi
movq %rax, 0x170(%rsp)
callq 0xd850
movq %rax, 0x168(%rsp)
movq 0x1b8(%rsp), %rsi
leaq 0x110(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0xd080
movq 0x30(%rsp), %rdx
movq 0x170(%rsp), %rdi
movq 0x168(%rsp), %rsi
callq 0x8710
movq %rax, 0x38(%rsp)
jmp 0x807d
movq 0x90(%rsp), %rdi
movq 0x38(%rsp), %rax
movq %rax, 0x178(%rsp)
callq 0xd850
movq %rax, 0x108(%rsp)
leaq 0x178(%rsp), %rdi
leaq 0x108(%rsp), %rsi
callq 0xd880
movb %al, 0x2f(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x8820
movb 0x2f(%rsp), %al
testb $0x1, %al
jne 0x80d2
jmp 0x81c3
movq 0xa8(%rsp), %rdi
movq 0x2d8(%rsp), %rsi
movq 0x1b8(%rsp), %rdx
movq %rdi, %rcx
addq $0x10, %rcx
callq 0x60a0
testb $0x1, 0x2ce(%rsp)
je 0x81ae
movq 0xa0(%rsp), %rsi
movq 0x2d8(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0xe8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x4180
movq 0xa8(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x1b8(%rsp), %rcx
movq %rdi, %r8
addq $0x10, %r8
callq 0x6310
jmp 0x8153
leaq 0xe8(%rsp), %rdi
callq 0x46e8
jmp 0x81ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0x110(%rsp), %rdi
callq 0x8820
jmp 0x82be
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x46e8
jmp 0x82be
movq 0x1b8(%rsp), %rax
movq %rax, 0x2f0(%rsp)
jmp 0x82ae
movq 0xa0(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x4180
movq 0x90(%rsp), %rsi
movq 0x2d8(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0xd8c0
jmp 0x81fc
movq 0x10(%rsp), %rdx
movq 0xa8(%rsp), %rdi
movzbl 0x2ce(%rsp), %r9d
movzbl 0x2cf(%rsp), %r8d
andl $0x1, %r8d
andl $0x1, %r9d
leaq 0xc8(%rsp), %rsi
leaq 0xb0(%rsp), %rcx
callq 0x7ac0
movq %rax, 0x8(%rsp)
jmp 0x823f
movq 0x8(%rsp), %rax
movq %rax, 0x2f0(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0xd9c0
leaq 0xc8(%rsp), %rdi
callq 0x46e8
jmp 0x82ae
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
jmp 0x829f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2a0(%rsp)
movl %eax, 0x29c(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0xd9c0
leaq 0xc8(%rsp), %rdi
callq 0x46e8
jmp 0x82be
movq 0x2f0(%rsp), %rax
addq $0x2f8, %rsp            # imm = 0x2F8
retq
movq 0x2a0(%rsp), %rdi
callq 0x45f0
nopl (%rax,%rax)