// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]ramulator/src/SALP.cpp
// Function: ramulator::SALP::init_prereq()
void SALP::init_prereq()
{
    prereq[int(Level::Rank)][int(Command::RD)] = [] (DRAM<SALP>* 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::WR)] = prereq[int(Level::Rank)][int(Command::RD)];

    switch(int(type)){
        case int(Type::SALP_1):
            prereq[int(Level::Bank)][int(Command::RD)] = [] (DRAM<SALP>* node, Command cmd, int id) {
                switch (int(node->state)){
                    case int(State::Closed): return Command::ACT;
                    case int(State::Opened):
                        return Command::MAX;
                    default: assert(false);}};
            prereq[int(Level::Bank)][int(Command::WR)] = prereq[int(Level::Bank)][int(Command::RD)];
            prereq[int(Level::SubArray)][int(Command::RD)] = [] (DRAM<SALP>* node, Command cmd, int id) {
              if (node->row_state.find(id) != node->row_state.end()) {
                return cmd;
              } else if (node->row_state.size()) {
                return Command::PRE;
              } else {
                return Command::PRE_OTHER;
              }
            };
            prereq[int(Level::SubArray)][int(Command::WR)] = prereq[int(Level::SubArray)][int(Command::RD)];
            prereq[int(Level::Rank)][int(Command::REF)] = [] (DRAM<SALP>* node, Command cmd, int id) {
                for (auto bank : node->children) {
                    if (bank->state == State::Closed)
                        continue;
                    return Command::PRER;
                }
                return Command::REF;};
            break;
        case int(Type::SALP_2):
            prereq[int(Level::SubArray)][int(Command::RD)] = [] (DRAM<SALP>* 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()) {
                          for (auto sa : node->parent->children) {
                              if (sa != node && sa->state == State::Opened) {
                                  return Command::PRE_OTHER;
                              }
                          }
                          return cmd;
                        } else {
                          // if this subarray has another row open, close it
                          // first
                          return Command::PRE;
                        }
                    default: assert(false);}};
            prereq[int(Level::SubArray)][int(Command::WR)] = prereq[int(Level::SubArray)][int(Command::RD)];
            prereq[int(Level::Rank)][int(Command::REF)] = [] (DRAM<SALP>* node, Command cmd, int id) {
                for (auto bank : node->children)
                    for (auto sa : bank->children) {
                        if (sa->state == State::Closed)
                            continue;
                        return Command::PRER;
                    }
                return Command::REF;};
            break;
        case int(Type::MASA):
            prereq[int(Level::SubArray)][int(Command::RD)] = [] (DRAM<SALP>* 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 Command::SASEL;
                        else return Command::PRE;
                    case int(State::Selected):
                        if (node->row_state.find(id) != node->row_state.end()) return cmd;
                        else return Command::PRE;
                    default: assert(false);
                }};
            prereq[int(Level::SubArray)][int(Command::WR)] = prereq[int(Level::SubArray)][int(Command::RD)];
            prereq[int(Level::Rank)][int(Command::REF)] = [] (DRAM<SALP>* node, Command cmd, int id) {
                for (auto bank : node->children)
                    for (auto sa : bank->children){
                        if (sa->state == State::Closed)
                            continue;
                        return Command::PRER;
                    }
                return Command::REF;};
            break;
        default: assert(false);
    }
    // PD
    prereq[int(Level::Rank)][int(Command::PDE)] = [] (DRAM<SALP>* 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<SALP>* 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 %rbx
subq $0x20, %rsp
movq %rdi, %rbx
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
leaq 0x35ec(%rip), %rcx      # 0x1381a0
movq %rcx, 0x18(%rsp)
leaq 0x361e(%rip), %rdx      # 0x1381de
movq %rdx, 0x10(%rsp)
movups 0x490(%rdi), %xmm1
movaps %xmm1, (%rsp)
movups %xmm0, 0x490(%rdi)
movq 0x4a0(%rdi), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x4a0(%rdi)
movq 0x4a8(%rdi), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x4a8(%rdi)
testq %rax, %rax
je 0x134c0f
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x490(%rbx), %rsi
leaq 0x4b0(%rbx), %rdi
callq 0x13937a
movl 0x20(%rbx), %eax
cmpl $0x2, %eax
je 0x134e97
cmpl $0x1, %eax
je 0x134da9
testl %eax, %eax
jne 0x135054
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x35a9(%rip), %rcx      # 0x1381f6
movq %rcx, 0x18(%rsp)
leaq 0x35d7(%rip), %rdx      # 0x138230
movq %rdx, 0x10(%rsp)
movups 0x650(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x650(%rbx)
movq 0x660(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x660(%rbx)
movq 0x668(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x668(%rbx)
testq %rax, %rax
je 0x134ca8
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x650(%rbx), %rsi
leaq 0x670(%rbx), %rdi
callq 0x13937a
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x357f(%rip), %rcx      # 0x138248
movq %rcx, 0x18(%rsp)
leaq 0x35db(%rip), %rdx      # 0x1382b0
movq %rdx, 0x10(%rsp)
movups 0x810(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x810(%rbx)
movq 0x820(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x820(%rbx)
movq 0x828(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x828(%rbx)
testq %rax, %rax
je 0x134d24
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x810(%rbx), %rsi
leaq 0x830(%rbx), %rdi
callq 0x13937a
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
leaq 0x3583(%rip), %rcx      # 0x1382c8
movq %rcx, 0x18(%rsp)
leaq 0x35ab(%rip), %rdx      # 0x1382fc
movq %rdx, 0x10(%rsp)
movups 0x510(%rbx), %xmm1
movaps %xmm1, (%rsp)
movups %xmm0, 0x510(%rbx)
movq 0x520(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x520(%rbx)
movq 0x528(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x528(%rbx)
testq %rax, %rax
je 0x134f7c
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x134f7c
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x355d(%rip), %rcx      # 0x138314
movq %rcx, 0x18(%rsp)
leaq 0x3619(%rip), %rdx      # 0x1383dc
movq %rdx, 0x10(%rsp)
movups 0x810(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x810(%rbx)
movq 0x820(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x820(%rbx)
movq 0x828(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x828(%rbx)
testq %rax, %rax
je 0x134e12
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x810(%rbx), %rsi
leaq 0x830(%rbx), %rdi
callq 0x13937a
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x35c1(%rip), %rcx      # 0x1383f4
movq %rcx, 0x18(%rsp)
leaq 0x361b(%rip), %rdx      # 0x13845a
movq %rdx, 0x10(%rsp)
movups 0x510(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x510(%rbx)
movq 0x520(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x520(%rbx)
movq 0x528(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x528(%rbx)
testq %rax, %rax
je 0x134f7c
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
jmp 0x134f7c
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x35cd(%rip), %rcx      # 0x138472
movq %rcx, 0x18(%rsp)
leaq 0x36a5(%rip), %rdx      # 0x138556
movq %rdx, 0x10(%rsp)
movups 0x810(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x810(%rbx)
movq 0x820(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x820(%rbx)
movq 0x828(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x828(%rbx)
testq %rax, %rax
je 0x134f00
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
leaq 0x810(%rbx), %rsi
leaq 0x830(%rbx), %rdi
callq 0x13937a
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x364d(%rip), %rcx      # 0x13856e
movq %rcx, 0x18(%rsp)
leaq 0x36a7(%rip), %rdx      # 0x1385d4
movq %rdx, 0x10(%rsp)
movups 0x510(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x510(%rbx)
movq 0x520(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x520(%rbx)
movq 0x528(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x528(%rbx)
testq %rax, %rax
je 0x134f7c
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x3662(%rip), %rcx      # 0x1385ec
movq %rcx, 0x18(%rsp)
leaq 0x3694(%rip), %rdx      # 0x13862a
movq %rdx, 0x10(%rsp)
movups 0x530(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x530(%rbx)
movq 0x540(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x540(%rbx)
movq 0x548(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x548(%rbx)
testq %rax, %rax
je 0x134fe5
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
xorps %xmm1, %xmm1
movaps %xmm1, (%rsp)
leaq 0x364f(%rip), %rcx      # 0x138642
movq %rcx, 0x18(%rsp)
leaq 0x3681(%rip), %rdx      # 0x138680
movq %rdx, 0x10(%rsp)
movups 0x570(%rbx), %xmm0
movaps %xmm0, (%rsp)
movups %xmm1, 0x570(%rbx)
movq 0x580(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rdx, 0x580(%rbx)
movq 0x588(%rbx), %rdx
movq %rdx, 0x18(%rsp)
movq %rcx, 0x588(%rbx)
testq %rax, %rax
je 0x13504e
movq %rsp, %rdi
movq %rdi, %rsi
movl $0x3, %edx
callq *%rax
addq $0x20, %rsp
popq %rbx
retq
leaq 0x182fe(%rip), %rdi     # 0x14d359
leaq 0x294b1(%rip), %rsi     # 0x15e513
leaq 0x29507(%rip), %rcx     # 0x15e570
movl $0xc8, %edx
callq 0xb200
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
jmp 0x135085
movq %rax, %rdi
callq 0x1718f
nop