// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/ssd/TSU_Priority_OutOfOrder.cpp
// Function: SSD_Components::TSU_Priority_OutOfOrder::get_next_write_service_queue(NVM::FlashMemory::Flash_Chip*)
Flash_Transaction_Queue *TSU_Priority_OutOfOrder::get_next_write_service_queue(NVM::FlashMemory::Flash_Chip *chip)
{
    if (UserWriteTRQueue[chip->ChannelID][chip->ChipID][IO_Flow_Priority_Class::URGENT].size() > 0)
    {
        return &UserWriteTRQueue[chip->ChannelID][chip->ChipID][IO_Flow_Priority_Class::URGENT];
    }

    int numberOfTries = 0;
    while (numberOfTries < IO_Flow_Priority_Class::get_scheduling_weight(IO_Flow_Priority_Class::HIGH))
    {
        nextPriorityClassWrite[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::to_priority((nextPriorityClassWrite[chip->ChannelID][chip->ChipID] + 1) % IO_Flow_Priority_Class::NUMBER_OF_PRIORITY_LEVELS);
        if (nextPriorityClassWrite[chip->ChannelID][chip->ChipID] == IO_Flow_Priority_Class::URGENT)
        {
            nextPriorityClassWrite[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::HIGH;
        }
        if (nextPriorityClassWrite[chip->ChannelID][chip->ChipID] == IO_Flow_Priority_Class::HIGH)
        {
            numberOfTries++;
            currentWeightWrite[chip->ChannelID][chip->ChipID]--;
            if (currentWeightWrite[chip->ChannelID][chip->ChipID] <= 0)
            {
                currentWeightWrite[chip->ChannelID][chip->ChipID] = IO_Flow_Priority_Class::get_scheduling_weight(IO_Flow_Priority_Class::HIGH);
            }
        }
        if (IO_Flow_Priority_Class::get_scheduling_weight(nextPriorityClassWrite[chip->ChannelID][chip->ChipID]) >= currentWeightWrite[chip->ChannelID][chip->ChipID]
            && UserWriteTRQueue[chip->ChannelID][chip->ChipID][nextPriorityClassWrite[chip->ChannelID][chip->ChipID]].size() > 0)
        {
            return &UserWriteTRQueue[chip->ChannelID][chip->ChipID][nextPriorityClassWrite[chip->ChannelID][chip->ChipID]];
        }
    }

    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq 0xb8(%rdi), %rax
movl 0x2c(%rsi), %ecx
movl 0x30(%rsi), %edx
movq (%rax,%rcx,8), %rax
movq (%rax,%rdx,8), %rax
cmpq $0x0, 0x18(%rax)
jne 0x51594
movq %rsi, %rbx
movq %rdi, %r14
movq 0xf0(%rdi), %rax
movq (%rax,%rcx,8), %rax
movl (%rax,%rdx,4), %esi
leaq 0x9354(%rip), %r15      # 0x5a80c
xorl %ebp, %ebp
leal 0x1(%rsi), %eax
leal 0x4(%rsi), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
andl $-0x4, %ecx
negl %ecx
leal (%rsi,%rcx), %edi
incl %edi
callq 0x51748
movq 0xf0(%r14), %rsi
movl 0x2c(%rbx), %edx
movl 0x30(%rbx), %ecx
movq (%rsi,%rdx,8), %rdi
movl %eax, (%rdi,%rcx,4)
cmpl $0x1, %eax
je 0x514f8
testl %eax, %eax
jne 0x51525
movl $0x1, (%rdi,%rcx,4)
incl %ebp
movq 0x100(%r14), %rax
movq (%rax,%rdx,8), %rdx
decl (%rdx,%rcx,4)
movl 0x2c(%rbx), %edx
movl 0x30(%rbx), %ecx
movq (%rax,%rdx,8), %rax
cmpl $0x0, (%rax,%rcx,4)
jg 0x51525
movl $0x4, (%rax,%rcx,4)
movl 0x2c(%rbx), %edx
movl 0x30(%rbx), %ecx
movq (%rsi,%rdx,8), %rax
movl (%rax,%rcx,4), %esi
cmpq $0x3, %rsi
ja 0x51550
movslq (%r15,%rsi,4), %rax
addq %r15, %rax
jmpq *%rax
movl $0x4, %eax
jmp 0x51552
movl $0x2, %eax
jmp 0x51552
movl $0x1, %eax
jmp 0x51552
xorl %eax, %eax
movq 0x100(%r14), %rdi
movq (%rdi,%rdx,8), %rdi
cmpl (%rdi,%rcx,4), %eax
jl 0x51584
movq 0xb8(%r14), %rax
movq (%rax,%rdx,8), %rax
movq (%rax,%rcx,8), %rax
movq %rsi, %rcx
shlq $0x8, %rcx
leaq (%rcx,%rsi,8), %rcx
cmpq $0x0, 0x18(%rax,%rcx)
jne 0x51591
cmpl $0x4, %ebp
jl 0x514ba
xorl %eax, %eax
jmp 0x51594
addq %rcx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop