// File: CMU-SAFARI[P]ramulator/src/DSARP.cpp
// Function: ramulator::DSARP::init_lambda()
void DSARP::init_lambda()
{
  // RANK
  lambda[int(Level::Rank)][int(Command::PREA)] = [] (DRAM<DSARP>* node, int id) {
    node->row_state.clear();
    for (auto bank : node->children) {
      bank->state = State::Closed;
      bank->row_state.clear();
      for (auto sa : bank->children){
        sa->state = State::Closed;
        sa->row_state.clear();}}};
  lambda[int(Level::Rank)][int(Command::REF)] = [] (DRAM<DSARP>* node, int id) {};

  // Power down related commands
  lambda[int(Level::Rank)][int(Command::PDE)] = [] (DRAM<DSARP>* node, int id) {
    for (auto bank : node->children) {
      if (bank->state == State::Closed)
        continue;
      node->state = State::ActPowerDown;
      return;
    }
    node->state = State::PrePowerDown;};
  lambda[int(Level::Rank)][int(Command::PDX)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::PowerUp;};
  lambda[int(Level::Rank)][int(Command::SRE)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::SelfRefresh;};
  lambda[int(Level::Rank)][int(Command::SRX)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::PowerUp;};

  // Open a row
  lambda[int(Level::Bank)][int(Command::ACT)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Opened;
    node->row_state[id] = State::Opened;};
  lambda[int(Level::SubArray)][int(Command::ACT)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Opened;
    node->row_state[id] = State::Opened;};

  // Close a bank
  lambda[int(Level::Bank)][int(Command::PRE)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Closed;
    node->row_state.clear();
    for (auto sa : node->children){
      sa->state = State::Closed;
      sa->row_state.clear();}};

  lambda[int(Level::Bank)][int(Command::RD)] = [] (DRAM<DSARP>* node, int id) {};
  lambda[int(Level::Bank)][int(Command::WR)] = [] (DRAM<DSARP>* node, int id) {};

  // Make sure the bank is closed after the column command
  lambda[int(Level::Bank)][int(Command::RDA)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Closed;
    node->row_state.clear();};

  lambda[int(Level::Bank)][int(Command::WRA)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Closed;
    node->row_state.clear();};

  // Nothing much, just make sure the bank is closed
  lambda[int(Level::Bank)][int(Command::REFPB)] = [] (DRAM<DSARP>* node, int id) {
    assert(node->state == State::Closed);
    node->row_state.clear();};

  // COL
  lambda[int(Level::SubArray)][int(Command::RDA)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Closed;
    node->row_state.clear();};
  lambda[int(Level::SubArray)][int(Command::WRA)] = [] (DRAM<DSARP>* node, int id) {
    node->state = State::Closed;
    node->row_state.clear();};

  // PowerDown -- this has not been tested
  lambda[int(Level::Rank)][int(Command::PDE)] = [] (DRAM<DSARP>* node, int id) {
    for (auto bank : node->children)
      for (auto sa : bank->children) {
        if (sa->state == State::Closed)
          continue;
        node->state = State::ActPowerDown;
        return;
      }
    node->state = State::PrePowerDown;};
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x28(%rbp)
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x40, %rdi
leaq -0x9(%rbp), %rsi
callq 0x1a8d30
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0xe0, %rdi
leaq -0xa(%rbp), %rsi
callq 0x1a8d80
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x120, %rdi            # imm = 0x120
leaq -0xb(%rbp), %rsi
callq 0x1a8dd0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x140, %rdi            # imm = 0x140
leaq -0xc(%rbp), %rsi
callq 0x1a8e20
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x160, %rdi            # imm = 0x160
leaq -0xd(%rbp), %rsi
callq 0x1a8e70
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x180, %rdi            # imm = 0x180
leaq -0xe(%rbp), %rsi
callq 0x1a8ec0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
leaq -0xf(%rbp), %rsi
callq 0x1a8f10
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x4e0, %rdi            # imm = 0x4E0
leaq -0x10(%rbp), %rsi
callq 0x1a8f60
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0x20, %rdi
leaq -0x11(%rbp), %rsi
callq 0x1a8fb0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0x60, %rdi
leaq -0x12(%rbp), %rsi
callq 0x1a9000
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0x80, %rdi
leaq -0x13(%rbp), %rsi
callq 0x1a9050
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0xa0, %rdi
leaq -0x14(%rbp), %rsi
callq 0x1a90a0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0xc0, %rdi
leaq -0x15(%rbp), %rsi
callq 0x1a90f0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x340, %rdi            # imm = 0x340
addq $0x100, %rdi            # imm = 0x100
leaq -0x16(%rbp), %rsi
callq 0x1a9140
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x4e0, %rdi            # imm = 0x4E0
addq $0xa0, %rdi
leaq -0x17(%rbp), %rsi
callq 0x1a9190
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x4e0, %rdi            # imm = 0x4E0
addq $0xc0, %rdi
leaq -0x18(%rbp), %rsi
callq 0x1a91e0
movq -0x28(%rbp), %rdi
addq $0x26a0, %rdi           # imm = 0x26A0
addq $0x1a0, %rdi            # imm = 0x1A0
addq $0x120, %rdi            # imm = 0x120
leaq -0x19(%rbp), %rsi
callq 0x1a9230
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)