// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]ramulator/src/LPDDR3.cpp
// Function: ramulator::LPDDR3::init_prereq()
void LPDDR3::init_prereq()
{
    // RD
    prereq[int(Level::Rank)][int(Command::RD)] = [] (DRAM<LPDDR3>* 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::SREFX;
            default: assert(false);
        }};
    prereq[int(Level::Bank)][int(Command::RD)] = [] (DRAM<LPDDR3>* node, Command cmd, int id) {
        switch (int(node->state)) {
            case int(State::Closed): return Command::ACT;
            case int(State::Opened):
                if (node->row_state.find(id) != node->row_state.end())
                    return cmd;
                return Command::PRE;
            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<LPDDR3>* node, Command cmd, int id) {
        for (auto bank : node->children) {
            if (bank->state == State::Closed)
                continue;
            return Command::PRA;
        }
        return Command::REF;};

    // REFPB
    prereq[int(Level::Bank)][int(Command::REFPB)] = [] (DRAM<LPDDR3>* node, Command cmd, int id) {
      if (node->state == State::Closed) return Command::REFPB;
        else return Command::PRE;};

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

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

// Assembly:
pushq %r14
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movups 0x400(%rdi), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x400(%rdi)
movq 0x410(%rdi), %rax
movq %rax, 0x10(%rsp)
leaq 0x2630(%rip), %rcx      # 0x121196
movq %rcx, 0x410(%rdi)
movq 0x418(%rdi), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25d8(%rip), %rcx      # 0x121158
movq %rcx, 0x418(%rdi)
testq %rax, %rax
je 0x11eb99
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movups 0x5a0(%rbx), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x5a0(%rbx)
movq 0x5b0(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x2675(%rip), %rcx      # 0x121236
movq %rcx, 0x5b0(%rbx)
movq 0x5b8(%rbx), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25d3(%rip), %rcx      # 0x1211ae
movq %rcx, 0x5b8(%rbx)
testq %rax, %rax
je 0x11ebf4
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x400(%rbx), %rsi
leaq 0x5a0(%rbx), %r14
leaq 0x420(%rbx), %rdi
callq 0x1218b4
leaq 0x5c0(%rbx), %rdi
movq %r14, %rsi
callq 0x1218b4
movups 0x480(%rbx), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x480(%rbx)
movq 0x490(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x263d(%rip), %rcx      # 0x121282
movq %rcx, 0x490(%rbx)
movq 0x498(%rbx), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25ef(%rip), %rcx      # 0x12124e
movq %rcx, 0x498(%rbx)
testq %rax, %rax
je 0x11ec78
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movups 0x640(%rbx), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x640(%rbx)
movq 0x650(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x2612(%rip), %rcx      # 0x1212b2
movq %rcx, 0x650(%rbx)
movq 0x658(%rbx), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25e0(%rip), %rcx      # 0x12129a
movq %rcx, 0x658(%rbx)
testq %rax, %rax
je 0x11ecd3
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movups 0x4c0(%rbx), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x4c0(%rbx)
movq 0x4d0(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x260d(%rip), %rcx      # 0x121308
movq %rcx, 0x4d0(%rbx)
movq 0x4d8(%rbx), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25b5(%rip), %rcx      # 0x1212ca
movq %rcx, 0x4d8(%rbx)
testq %rax, %rax
je 0x11ed2e
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
movups 0x500(%rbx), %xmm0
movaps %xmm0, (%rsp)
xorps %xmm0, %xmm0
movups %xmm0, 0x500(%rbx)
movq 0x510(%rbx), %rax
movq %rax, 0x10(%rsp)
leaq 0x2608(%rip), %rcx      # 0x12135e
movq %rcx, 0x510(%rbx)
movq 0x518(%rbx), %rcx
movq %rcx, 0x18(%rsp)
leaq 0x25b0(%rip), %rcx      # 0x121320
movq %rcx, 0x518(%rbx)
testq %rax, %rax
je 0x11ed89
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
addq $0x28, %rsp
popq %rbx
popq %r14
retq
jmp 0x11ed9b
jmp 0x11ed9b
jmp 0x11ed9b
jmp 0x11ed9b
jmp 0x11ed9b
movq %rax, %rdi
callq 0x171a3
nop