// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]ramulator/src/TLDRAM.cpp
// Function: ramulator::TLDRAM::init_prereq()
void TLDRAM::init_prereq()
{
    // RD
    prereq[int(Level::Rank)][int(Command::RD)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::PowerUp): return Command::MAX;
            case int(State::ActPowerDown): return Command::PDX;
            case int(State::PrePowerDown): return Command::PDX;
            case int(State::SelfRefresh): return Command::SRX;
            default: assert(false);
        }
    };
    prereq[int(Level::Rank)][int(Command::MIG)] = prereq[int(Level::Rank)][int(Command::RD)];

    prereq[int(Level::Bank)][int(Command::RD)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::Closed):
                if (id % node->spec->segment_ratio)
                    return Command::ACT;
                else
                    return Command::ACTF;
            case int(State::Opened):
                if (node->row_state.find(id) != node->row_state.end())
                    return cmd;
                if (id % node->spec->segment_ratio)
                    return Command::PRE;
                else
                    return Command::PREF;
            default: assert(false);
        }
    };
    prereq[int(Level::Bank)][int(Command::MIG)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::Closed):
                return Command::ACTM;
            case int(State::Opened):
                if (node->row_state.find(id) != node->row_state.end())
                    return cmd;
                return Command::PREM;
            default: assert(false);
        }
    };

    // WR
    prereq[int(Level::Rank)][int(Command::WR)] = prereq[int(Level::Rank)][int(Command::RD)];
    prereq[int(Level::Bank)][int(Command::WR)] = prereq[int(Level::Bank)][int(Command::RD)];

    // REF
    prereq[int(Level::Rank)][int(Command::REF)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        for (auto bank : node->children) {
            if (bank->state == State::Closed)
                continue;
            if (id % node->spec->segment_ratio)
                return Command::PREA;
            else
                return Command::PREAF;
        }
        return Command::REF;
    };

    // PD
    prereq[int(Level::Rank)][int(Command::PDE)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::PowerUp): return Command::PDE;
            case int(State::ActPowerDown): return Command::PDE;
            case int(State::PrePowerDown): return Command::PDE;
            case int(State::SelfRefresh): return Command::SRX;
            default: assert(false);
        }
    };

    // SR
    prereq[int(Level::Rank)][int(Command::SRE)] = [] (DRAM<TLDRAM>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::PowerUp): return Command::SRE;
            case int(State::ActPowerDown): return Command::PDX;
            case int(State::PrePowerDown): return Command::PDX;
            case int(State::SelfRefresh): return Command::SRE;
            default: assert(false);
        }
    };
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rdi, %rbx
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3b1e(%rip), %rcx      # 0x1437ae
movq %rcx, 0x18(%rsp)
leaq 0x3b50(%rip), %rdx      # 0x1437ec
movq %rdx, 0x10(%rsp)
movups 0x518(%rdi), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x518(%rdi)
movq 0x528(%rdi), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x528(%rdi)
movq 0x530(%rdi), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x530(%rdi)
testq %rax, %rax
je 0x13fceb
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x518(%rbx), %r14
leaq 0x658(%rbx), %rdi
movq %r14, %rsi
callq 0x144160
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3af5(%rip), %rcx      # 0x143804
movq %rcx, 0x18(%rsp)
leaq 0x3ba1(%rip), %rdx      # 0x1438bc
movq %rdx, 0x10(%rsp)
movups 0x738(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x738(%rbx)
movq 0x748(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x748(%rbx)
movq 0x750(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x750(%rbx)
testq %rax, %rax
je 0x13fd6a
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3b5c(%rip), %rcx      # 0x1438d4
movq %rcx, 0x18(%rsp)
leaq 0x3bdc(%rip), %rdx      # 0x143960
movq %rdx, 0x10(%rsp)
movups 0x878(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x878(%rbx)
movq 0x888(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x888(%rbx)
movq 0x890(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x890(%rbx)
testq %rax, %rax
je 0x13fdd3
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x738(%rbx), %r15
leaq 0x538(%rbx), %rdi
movq %r14, %rsi
callq 0x144160
leaq 0x758(%rbx), %rdi
movq %r15, %rsi
callq 0x144160
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3b72(%rip), %rcx      # 0x143978
movq %rcx, 0x18(%rsp)
leaq 0x3bc6(%rip), %rdx      # 0x1439d8
movq %rdx, 0x10(%rsp)
movups 0x558(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x558(%rbx)
movq 0x568(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x568(%rbx)
movq 0x570(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x570(%rbx)
testq %rax, %rax
je 0x13fe61
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3b81(%rip), %rcx      # 0x1439f0
movq %rcx, 0x18(%rsp)
leaq 0x3bb3(%rip), %rdx      # 0x143a2e
movq %rdx, 0x10(%rsp)
movups 0x578(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x578(%rbx)
movq 0x588(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x588(%rbx)
movq 0x590(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x590(%rbx)
testq %rax, %rax
je 0x13feca
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3b6e(%rip), %rcx      # 0x143a46
movq %rcx, 0x18(%rsp)
leaq 0x3ba0(%rip), %rdx      # 0x143a84
movq %rdx, 0x10(%rsp)
movups 0x5b8(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x5b8(%rbx)
movq 0x5c8(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x5c8(%rbx)
movq 0x5d0(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x5d0(%rbx)
testq %rax, %rax
je 0x13ff33
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
jmp 0x13ff47
jmp 0x13ff47
jmp 0x13ff47
jmp 0x13ff47
jmp 0x13ff47
movq %rax, %rdi
callq 0x1718f
nop