// File: /workspace/github_cpp_makefile_star2_O2/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 $0x640, %eax            # imm = 0x640
je 0xa2226
cmpl $0xc80, %eax            # imm = 0xC80
je 0xa2222
cmpl $0x855, %eax            # imm = 0x855
je 0xa222a
cmpl $0x960, %eax            # imm = 0x960
je 0xa222e
cmpl $0x74a, %eax            # imm = 0x74A
jne 0xa232a
pushq $0x1
jmp 0xa2230
pushq $0x4
jmp 0xa2230
xorl %eax, %eax
jmp 0xa2231
pushq $0x2
jmp 0xa2230
pushq $0x3
popq %rax
movl 0x2dc0(%rdi), %ecx
sarl $0xa, %ecx
cmpl $0x2, %ecx
je 0xa2256
cmpl $0x8, %ecx
je 0xa2251
cmpl $0x4, %ecx
jne 0xa2311
pushq $0x1
jmp 0xa2253
pushq $0x2
popq %rdx
jmp 0xa2258
xorl %edx, %edx
movl 0x2dc4(%rdi), %ecx
xorl %esi, %esi
cmpl $0x10, %ecx
sete %sil
imulq $0x14, %rsi, %rsi
leaq 0x3bc4e(%rip), %r8      # 0xddec0
addq %rsi, %r8
shll $0x2, %eax
movl (%rax,%r8), %r8d
movl %r8d, 0x32c0(%rdi)
leaq 0x3bc66(%rip), %r8      # 0xddef0
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
imulq $0x14, %r8, %rcx
leaq 0x3bc68(%rip), %rsi     # 0xddf20
addq %rcx, %rsi
movl (%rax,%rsi), %ecx
movl %ecx, 0x32c8(%rdi)
movslq 0x2de0(%rdi), %rcx
imulq $0x3c, %rcx, %rsi
leaq 0x3bc8a(%rip), %r8      # 0xddf60
imulq $0x14, %rdx, %rdx
addq %rdx, %r8
addq %rsi, %r8
movl (%rax,%r8), %esi
movl %esi, 0x32cc(%rdi)
leaq 0x3bd2f(%rip), %rsi     # 0xde020
movl (%rax,%rsi), %esi
sarl %cl, %esi
movl %esi, 0x32d0(%rdi)
leaq 0x3bd3d(%rip), %rcx     # 0xde040
addq %rdx, %rcx
movl (%rax,%rcx), %eax
movl %eax, 0x32e4(%rdi)
popq %rax
retq
leaq 0x2f041(%rip), %rdi     # 0xd1359
leaq 0x3b8d1(%rip), %rsi     # 0xddbf0
leaq 0x3b8d7(%rip), %rcx     # 0xddbfd
pushq $0x6a
jmp 0xa2341
leaq 0x2f028(%rip), %rdi     # 0xd1359
leaq 0x3b8b8(%rip), %rsi     # 0xddbf0
leaq 0x3b8be(%rip), %rcx     # 0xddbfd
pushq $0x64
popq %rdx
callq 0xb210
nop