// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]ramulator/src/DDR4.cpp
// Function: ramulator::DDR4::init_speed()
void DDR4::init_speed()
{
    const static int RRDS_TABLE[2][5] = {
        {4, 4, 4, 4, 4},
        {5, 5, 6, 7, 9}
    };
    const static int RRDL_TABLE[2][5] = {
        {5, 5, 6, 6, 8},
        {6, 6, 7, 8, 11}
    };
    const static int FAW_TABLE[3][5] = {
        {16, 16, 16, 16, 16},
        {20, 22, 23, 26, 34},
        {28, 28, 32, 36, 48}
    };
    const static int RFC_TABLE[int(RefreshMode::MAX)][3][5] = {{   
            {128, 150, 171, 192, 256},
            {208, 243, 278, 312, 416},
            {280, 327, 374, 420, 560}
        },{
            {88, 103, 118, 132,  176},
            {128, 150, 171, 192, 256},
            {208, 243, 278, 312, 416} 
        },{
            {72, 84, 96, 108, 144},
            {88, 103, 118, 132, 176},
            {128, 150, 171, 192, 256}  
        }
    };
    const static int REFI_TABLE[5] = {
        6240, 7280, 8320, 9360, 12480
    };
    const static int XS_TABLE[3][5] = {
        {136, 159, 182, 204, 272},
        {216, 252, 288, 324, 432},
        {288, 336, 384, 432, 576}
    };

    int speed = 0, density = 0;
    switch (speed_entry.rate) {
        case 1600: speed = 0; break;
        case 1866: speed = 1; break;
        case 2133: speed = 2; break;
        case 2400: speed = 3; break;
        case 3200: speed = 4; break;
        default: assert(false);
    };
    switch (org_entry.size >> 10){
        case 2: density = 0; break;
        case 4: density = 1; break;
        case 8: density = 2; break;
        default: assert(false);
    }
    speed_entry.nRRDS = RRDS_TABLE[org_entry.dq == 16? 1: 0][speed];
    speed_entry.nRRDL = RRDL_TABLE[org_entry.dq == 16? 1: 0][speed];
    speed_entry.nFAW = FAW_TABLE[org_entry.dq == 4? 0: org_entry.dq == 8? 1: 2][speed];
    speed_entry.nRFC = RFC_TABLE[(int)refresh_mode][density][speed];
    speed_entry.nREFI = (REFI_TABLE[speed] >> int(refresh_mode));
    speed_entry.nXS = XS_TABLE[density][speed];
}

// Assembly:
pushq %rax
movl 0x3270(%rdi), %eax
cmpl $0x854, %eax            # imm = 0x854
jle 0x10d0a2
cmpl $0x855, %eax            # imm = 0x855
je 0x10d0bb
cmpl $0x960, %eax            # imm = 0x960
je 0x10d0c2
cmpl $0xc80, %eax            # imm = 0xC80
jne 0x10d1d6
movl $0x4, %eax
jmp 0x10d0cb
cmpl $0x640, %eax            # imm = 0x640
je 0x10d0c9
cmpl $0x74a, %eax            # imm = 0x74A
jne 0x10d1d6
movl $0x1, %eax
jmp 0x10d0cb
movl $0x2, %eax
jmp 0x10d0cb
movl $0x3, %eax
jmp 0x10d0cb
xorl %eax, %eax
movl 0x2dc0(%rdi), %ecx
sarl $0xa, %ecx
cmpl $0x2, %ecx
je 0x10d0f5
cmpl $0x8, %ecx
je 0x10d0ee
cmpl $0x4, %ecx
jne 0x10d1b7
movl $0x1, %edx
jmp 0x10d0f7
movl $0x2, %edx
jmp 0x10d0f7
xorl %edx, %edx
movl 0x2dc4(%rdi), %ecx
xorl %esi, %esi
cmpl $0x10, %ecx
sete %sil
shll $0x2, %esi
leaq (%rsi,%rsi,4), %rsi
leaq 0x49e0c(%rip), %r8      # 0x156f20
addq %rsi, %r8
shll $0x2, %eax
movl (%rax,%r8), %r8d
movl %r8d, 0x32c0(%rdi)
leaq 0x49e24(%rip), %r8      # 0x156f50
addq %rsi, %r8
movl (%rax,%r8), %esi
movl %esi, 0x32c4(%rdi)
xorl %esi, %esi
cmpl $0x8, %ecx
setne %sil
incq %rsi
xorl %r8d, %r8d
cmpl $0x4, %ecx
cmovneq %rsi, %r8
leaq (%r8,%r8,4), %rcx
leaq 0x49e26(%rip), %rsi     # 0x156f80
leaq (%rsi,%rcx,4), %rcx
movl (%rax,%rcx), %ecx
movl %ecx, 0x32c8(%rdi)
movslq 0x2de0(%rdi), %rcx
imulq $0x3c, %rcx, %rsi
leaq 0x49e47(%rip), %r8      # 0x156fc0
shll $0x2, %edx
leaq (%rdx,%rdx,4), %rdx
addq %rdx, %r8
addq %rsi, %r8
movl (%rax,%r8), %esi
movl %esi, 0x32cc(%rdi)
leaq 0x49ee9(%rip), %rsi     # 0x157080
movl (%rax,%rsi), %esi
sarl %cl, %esi
movl %esi, 0x32d0(%rdi)
leaq 0x49ef7(%rip), %rcx     # 0x1570a0
addq %rdx, %rcx
movl (%rax,%rcx), %eax
movl %eax, 0x32e4(%rdi)
popq %rax
retq
leaq 0x3d1db(%rip), %rdi     # 0x14a399
leaq 0x49a88(%rip), %rsi     # 0x156c4d
leaq 0x49a8e(%rip), %rcx     # 0x156c5a
movl $0x6a, %edx
callq 0xb200
leaq 0x3d1bc(%rip), %rdi     # 0x14a399
leaq 0x49a69(%rip), %rsi     # 0x156c4d
leaq 0x49a6f(%rip), %rcx     # 0x156c5a
movl $0x64, %edx
callq 0xb200
nop