// File: CMU-SAFARI[P]ramulator/src/DRAM.h
// Function: ramulator::DRAM<ramulator::DDR3>::DRAM(ramulator::DDR3*, ramulator::DDR3::Level)
DRAM<T>::DRAM(T* spec, typename T::Level level) :
    spec(spec), level(level), id(0), parent(NULL)
{

    state = spec->start[(int)level];
    prereq = spec->prereq[int(level)];
    rowhit = spec->rowhit[int(level)];
    rowopen = spec->rowopen[int(level)];
    lambda = spec->lambda[int(level)];
    timing = spec->timing[int(level)];

    fill_n(next, int(T::Command::MAX), -1); // initialize future
    for (int cmd = 0; cmd < int(T::Command::MAX); cmd++) {
        int dist = 0;
        for (auto& t : timing[cmd])
            dist = max(dist, t.dist);

        if (dist)
            prev[cmd].resize(dist, -1); // initialize history
    }

    // try to recursively construct my children
    int child_level = int(level) + 1;
    if (child_level == int(T::Level::Row))
        return; // stop recursion: rows are not instantiated as nodes

    int child_max = spec->org_entry.count[child_level];
    if (!child_max)
        return; // stop recursion: the number of children is unspecified

    // recursively construct my children
    for (int i = 0; i < child_max; i++) {
        DRAM<T>* child = new DRAM<T>(spec, typename T::Level(child_level));
        child->parent = this;
        child->id = i;
        children.push_back(child);
    }

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x80(%rbp)
movq %rdi, %rax
movq %rax, -0x88(%rbp)
callq 0x25e50
movq -0x80(%rbp), %rdi
addq $0x98, %rdi
movq %rdi, -0x78(%rbp)
callq 0x25e50
jmp 0x1dcf3
movq -0x88(%rbp), %rdi
addq $0x130, %rdi            # imm = 0x130
movq %rdi, -0x90(%rbp)
callq 0x25e50
jmp 0x1dd0f
movq -0x88(%rbp), %rdi
addq $0x1c8, %rdi            # imm = 0x1C8
movq %rdi, -0x98(%rbp)
callq 0x25e50
jmp 0x1dd2b
movq -0x88(%rbp), %rdi
addq $0x260, %rdi            # imm = 0x260
movq %rdi, -0xa0(%rbp)
callq 0x25e50
jmp 0x1dd47
movq -0x88(%rbp), %rdi
addq $0x2f8, %rdi            # imm = 0x2F8
movq %rdi, -0xa8(%rbp)
callq 0x25e50
jmp 0x1dd63
movq -0x88(%rbp), %rdi
movq -0x10(%rbp), %rax
movq %rax, 0x390(%rdi)
movl -0x14(%rbp), %eax
movl %eax, 0x398(%rdi)
movl $0x0, 0x39c(%rdi)
movq $0x0, 0x3a8(%rdi)
addq $0x3b0, %rdi            # imm = 0x3B0
movq %rdi, -0xd8(%rbp)
callq 0x25e70
movq -0x88(%rbp), %rdi
addq $0x3d0, %rdi            # imm = 0x3D0
movq %rdi, -0xd0(%rbp)
callq 0x25e90
movq -0x88(%rbp), %rdi
movl $0x0, 0x400(%rdi)
movq $-0x1, 0x408(%rdi)
movq $-0x1, 0x410(%rdi)
movq $-0x1, 0x418(%rdi)
movq $-0x1, 0x420(%rdi)
movq $-0x1, 0x428(%rdi)
addq $0x430, %rdi            # imm = 0x430
movq %rdi, -0xc8(%rbp)
callq 0x25eb0
movq -0x88(%rbp), %rax
movq $0x0, 0x448(%rax)
addq $0x4b0, %rax            # imm = 0x4B0
movq %rax, -0xc0(%rbp)
movq %rax, %rcx
addq $0x3c0, %rcx            # imm = 0x3C0
movq %rcx, -0xb8(%rbp)
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
movq %rdi, -0xe0(%rbp)
callq 0x25ed0
jmp 0x1de67
movq -0xb8(%rbp), %rcx
movq -0xe0(%rbp), %rax
addq $0x50, %rax
cmpq %rcx, %rax
movq %rax, -0xb0(%rbp)
jne 0x1de52
movq -0x88(%rbp), %rdi
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
movl 0x1b0(%rax,%rcx,4), %eax
movl %eax, 0x3c8(%rdi)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x7, %rcx
leaq 0x1e0(%rax,%rcx), %rax
movq %rax, 0x870(%rdi)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x7, %rcx
leaq 0x960(%rax,%rcx), %rax
movq %rax, 0x878(%rdi)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x7, %rcx
leaq 0x10e0(%rax,%rcx), %rax
movq %rax, 0x880(%rdi)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x7, %rcx
leaq 0x1e00(%rax,%rcx), %rax
movq %rax, 0x888(%rdi)
movq -0x10(%rbp), %rax
movslq -0x14(%rbp), %rcx
leaq (%rcx,%rcx,8), %rcx
shlq $0x5, %rcx
leaq 0x1860(%rax,%rcx), %rax
movq %rax, 0x890(%rdi)
addq $0x450, %rdi            # imm = 0x450
movl $0xffffffff, -0x28(%rbp) # imm = 0xFFFFFFFF
movl $0xc, %esi
leaq -0x28(%rbp), %rdx
callq 0x25f60
jmp 0x1df5a
movl $0x0, -0x2c(%rbp)
cmpl $0xc, -0x2c(%rbp)
jge 0x1e107
movq -0x88(%rbp), %rax
movl $0x0, -0x30(%rbp)
movq 0x890(%rax), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
callq 0x25fb0
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
callq 0x25fe0
movq %rax, -0x48(%rbp)
leaq -0x40(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x26010
testb $0x1, %al
jne 0x1dfbf
jmp 0x1e0bd
leaq -0x40(%rbp), %rdi
callq 0x26050
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
addq $0x4, %rsi
leaq -0x30(%rbp), %rdi
callq 0x26070
movq %rax, -0xe8(%rbp)
jmp 0x1dfe6
movq -0xe8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x30(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x260b0
jmp 0x1dfa9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e288
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e27f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e273
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e267
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e25b
movq -0xc0(%rbp), %rcx
movq %rax, %rsi
movq -0xe0(%rbp), %rax
movq %rsi, -0x20(%rbp)
movl %edx, -0x24(%rbp)
cmpq %rax, %rcx
movq %rax, -0xf0(%rbp)
je 0x1e0a7
movq -0xf0(%rbp), %rdi
addq $-0x50, %rdi
movq %rdi, -0xf8(%rbp)
callq 0x25ef0
movq -0xc0(%rbp), %rcx
movq -0xf8(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0xf0(%rbp)
jne 0x1e076
jmp 0x1e22b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0x1e1e4
cmpl $0x0, -0x30(%rbp)
je 0x1e0f7
movq -0x88(%rbp), %rax
movslq -0x2c(%rbp), %rcx
leaq (%rcx,%rcx,4), %rcx
shlq $0x4, %rcx
leaq 0x4b0(%rax,%rcx), %rdi
movslq -0x30(%rbp), %rsi
movq $-0x1, -0x58(%rbp)
leaq -0x58(%rbp), %rdx
callq 0x260d0
jmp 0x1e0f5
jmp 0x1e0f7
jmp 0x1e0f9
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x1df61
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
cmpl $0x3, -0x5c(%rbp)
jne 0x1e11b
jmp 0x1e1db
movq -0x10(%rbp), %rax
movslq -0x5c(%rbp), %rcx
movl 0x272c(%rax,%rcx,4), %eax
movl %eax, -0x60(%rbp)
cmpl $0x0, -0x60(%rbp)
jne 0x1e138
jmp 0x1e1db
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x60(%rbp), %eax
jge 0x1e1db
movl $0x898, %edi            # imm = 0x898
callq 0xc360
movq %rax, -0x100(%rbp)
jmp 0x1e15e
movq -0x100(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl -0x5c(%rbp), %edx
callq 0x1dcb0
jmp 0x1e173
movq -0x88(%rbp), %rdi
movq -0x100(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rax
movq %rdi, 0x3a8(%rax)
movl -0x64(%rbp), %ecx
movq -0x70(%rbp), %rax
movl %ecx, 0x39c(%rax)
addq $0x3b0, %rdi            # imm = 0x3B0
leaq -0x70(%rbp), %rsi
callq 0x26160
jmp 0x1e1af
jmp 0x1e1b1
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x1e13f
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x898, %esi            # imm = 0x898
callq 0xc370
jmp 0x1e1e4
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
movq -0xc0(%rbp), %rax
addq $0x3c0, %rax            # imm = 0x3C0
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
addq $-0x50, %rdi
movq %rdi, -0x110(%rbp)
callq 0x25ef0
movq -0xc0(%rbp), %rcx
movq -0x110(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x108(%rbp)
jne 0x1e1f8
jmp 0x1e22b
movq -0xc8(%rbp), %rdi
callq 0x261d0
movq -0xd0(%rbp), %rdi
callq 0x26230
movq -0xd8(%rbp), %rdi
callq 0x26250
movq -0xa8(%rbp), %rdi
callq 0x262b0
movq -0xa0(%rbp), %rdi
callq 0x262b0
movq -0x98(%rbp), %rdi
callq 0x262b0
movq -0x90(%rbp), %rdi
callq 0x262b0
movq -0x78(%rbp), %rdi
callq 0x262b0
movq -0x80(%rbp), %rdi
callq 0x262b0
movq -0x20(%rbp), %rdi
callq 0xc5d0
nopw (%rax,%rax)