// File: Merulo[P]CompilerJFTT/src/Register/RegisterBlock.cpp
// Function: RegisterBlock::getRegistersForOperation(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>>>)
Register& RegisterBlock::getRegistersForOperation(std::string name, Block& b, std::vector<std::reference_wrapper<Register>> usedRegisters)
{
    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)
        {
            saveToMemory(b, reg, _addressRegister);
            return reg;
        }
    }

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

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

    return getRegistersForOperation(name, b, usedRegisters);     
}

// Assembly:
subq $0x228, %rsp            # imm = 0x228
movq %rsi, 0x68(%rsp)
movq %rcx, 0x70(%rsp)
movq %rdi, 0x218(%rsp)
movq %rsi, 0x210(%rsp)
movq %rdx, 0x208(%rsp)
movq %rcx, 0x200(%rsp)
movq 0x218(%rsp), %rax
movq %rax, 0x78(%rsp)
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 0x7452
jmp 0x75a3
leaq 0x1f0(%rsp), %rdi
callq 0xd7b0
movq 0x70(%rsp), %rdi
movq %rax, 0x1e0(%rsp)
callq 0xd820
movq 0x70(%rsp), %rdi
movq %rax, 0x1d0(%rsp)
callq 0xd850
movq %rax, 0x1c8(%rsp)
movq 0x1e0(%rsp), %rsi
leaq 0x170(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0xd080
movq 0x58(%rsp), %rdx
movq 0x1d0(%rsp), %rdi
movq 0x1c8(%rsp), %rsi
callq 0x7880
movq %rax, 0x60(%rsp)
jmp 0x74c6
movq 0x70(%rsp), %rdi
movq 0x60(%rsp), %rax
movq %rax, 0x1d8(%rsp)
callq 0xd850
movq %rax, 0x158(%rsp)
leaq 0x1d8(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0xd7e0
movb %al, 0x57(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x7990
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x7515
jmp 0x753d
jmp 0x7591
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0x170(%rsp), %rdi
callq 0x7990
jmp 0x786c
movq 0x68(%rsp), %rsi
movq 0x1e0(%rsp), %rdi
addq $0x30, %rdi
callq 0xd2c0
testb $0x1, %al
jne 0x7559
jmp 0x758f
movq 0x78(%rsp), %rdi
movq 0x208(%rsp), %rsi
movq 0x1e0(%rsp), %rdx
movq %rdi, %rcx
addq $0x10, %rcx
callq 0x60a0
movq 0x1e0(%rsp), %rax
movq %rax, 0x220(%rsp)
jmp 0x785c
jmp 0x7591
leaq 0x1f0(%rsp), %rdi
callq 0xd7c0
jmp 0x7434
movq 0x78(%rsp), %rax
movq %rax, %rdi
addq $0x68, %rdi
movl 0x80(%rax), %eax
movl %eax, %esi
callq 0xd360
movq 0x78(%rsp), %rdi
movq %rax, 0x150(%rsp)
movl 0x80(%rdi), %eax
addl $0x1, %eax
movl %eax, 0x80(%rdi)
movl 0x80(%rdi), %eax
movq %rax, 0x48(%rsp)
addq $0x68, %rdi
callq 0xd2a0
movq %rax, %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
jne 0x7608
movq 0x78(%rsp), %rax
movl $0x0, 0x80(%rax)
movq 0x70(%rsp), %rdi
callq 0xd820
movq 0x70(%rsp), %rdi
movq %rax, 0x140(%rsp)
callq 0xd850
movq %rax, 0x138(%rsp)
movq 0x150(%rsp), %rsi
leaq 0xe0(%rsp), %rdi
movq %rdi, 0x38(%rsp)
callq 0xd080
movq 0x38(%rsp), %rdx
movq 0x140(%rsp), %rdi
movq 0x138(%rsp), %rsi
callq 0x79a0
movq %rax, 0x40(%rsp)
jmp 0x7667
movq 0x70(%rsp), %rdi
movq 0x40(%rsp), %rax
movq %rax, 0x148(%rsp)
callq 0xd850
movq %rax, 0xd8(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0xd880
movb %al, 0x37(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x7ab0
movb 0x37(%rsp), %al
testb $0x1, %al
jne 0x76b9
jmp 0x7794
movq 0x78(%rsp), %rdi
movq 0x208(%rsp), %rsi
movq 0x150(%rsp), %rdx
movq %rdi, %rcx
addq $0x10, %rcx
movq %rcx, 0x28(%rsp)
callq 0x60a0
movq 0x68(%rsp), %rsi
movq 0x208(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0xb8(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x4180
movq 0x78(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rdx
movq 0x28(%rsp), %r8
movq 0x150(%rsp), %rcx
callq 0x6310
jmp 0x7726
leaq 0xb8(%rsp), %rdi
callq 0x46e8
movq 0x150(%rsp), %rax
movq %rax, 0x220(%rsp)
jmp 0x785c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x7ab0
jmp 0x786c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x46e8
jmp 0x786c
movq 0x68(%rsp), %rsi
leaq 0x98(%rsp), %rdi
callq 0x4180
movq 0x70(%rsp), %rsi
movq 0x208(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x80(%rsp), %rdi
callq 0xd8c0
jmp 0x77c7
movq 0x10(%rsp), %rdx
movq 0x78(%rsp), %rdi
leaq 0x98(%rsp), %rsi
leaq 0x80(%rsp), %rcx
callq 0x73c0
movq %rax, 0x8(%rsp)
jmp 0x77ed
movq 0x8(%rsp), %rax
movq %rax, 0x220(%rsp)
leaq 0x80(%rsp), %rdi
callq 0xd9c0
leaq 0x98(%rsp), %rdi
callq 0x46e8
jmp 0x785c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
jmp 0x784d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0x80(%rsp), %rdi
callq 0xd9c0
leaq 0x98(%rsp), %rdi
callq 0x46e8
jmp 0x786c
movq 0x220(%rsp), %rax
addq $0x228, %rsp            # imm = 0x228
retq
movq 0x168(%rsp), %rdi
callq 0x45f0
nopl (%rax)