// File: /workspace/github_cpp_makefile_star2_O1/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 0x110054
cmpl $0x855, %eax            # imm = 0x855
je 0x11006d
cmpl $0x960, %eax            # imm = 0x960
je 0x110074
cmpl $0xc80, %eax            # imm = 0xC80
jne 0x110188
movl $0x4, %eax
jmp 0x11007d
cmpl $0x640, %eax            # imm = 0x640
je 0x11007b
cmpl $0x74a, %eax            # imm = 0x74A
jne 0x110188
movl $0x1, %eax
jmp 0x11007d
movl $0x2, %eax
jmp 0x11007d
movl $0x3, %eax
jmp 0x11007d
xorl %eax, %eax
movl 0x2dc0(%rdi), %ecx
sarl $0xa, %ecx
cmpl $0x2, %ecx
je 0x1100a7
cmpl $0x8, %ecx
je 0x1100a0
cmpl $0x4, %ecx
jne 0x110169
movl $0x1, %edx
jmp 0x1100a9
movl $0x2, %edx
jmp 0x1100a9
xorl %edx, %edx
movl 0x2dc4(%rdi), %ecx
xorl %esi, %esi
cmpl $0x10, %ecx
sete %sil
shll $0x2, %esi
leaq (%rsi,%rsi,4), %rsi
leaq 0x49dfa(%rip), %r8      # 0x159ec0
addq %rsi, %r8
shll $0x2, %eax
movl (%rax,%r8), %r8d
movl %r8d, 0x32c0(%rdi)
leaq 0x49e12(%rip), %r8      # 0x159ef0
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 0x49e14(%rip), %rsi     # 0x159f20
leaq (%rsi,%rcx,4), %rcx
movl (%rax,%rcx), %ecx
movl %ecx, 0x32c8(%rdi)
movslq 0x2de0(%rdi), %rcx
imulq $0x3c, %rcx, %rsi
leaq 0x49e35(%rip), %r8      # 0x159f60
shll $0x2, %edx
leaq (%rdx,%rdx,4), %rdx
addq %rdx, %r8
addq %rsi, %r8
movl (%rax,%r8), %esi
movl %esi, 0x32cc(%rdi)
leaq 0x49ed7(%rip), %rsi     # 0x15a020
movl (%rax,%rsi), %esi
sarl %cl, %esi
movl %esi, 0x32d0(%rdi)
leaq 0x49ee5(%rip), %rcx     # 0x15a040
addq %rdx, %rcx
movl (%rax,%rcx), %eax
movl %eax, 0x32e4(%rdi)
popq %rax
retq
leaq 0x3d1e9(%rip), %rdi     # 0x14d359
leaq 0x49a76(%rip), %rsi     # 0x159bed
leaq 0x49a7c(%rip), %rcx     # 0x159bfa
movl $0x6a, %edx
callq 0xb200
leaq 0x3d1ca(%rip), %rdi     # 0x14d359
leaq 0x49a57(%rip), %rsi     # 0x159bed
leaq 0x49a5d(%rip), %rcx     # 0x159bfa
movl $0x64, %edx
callq 0xb200
nop