// File: niksram[P]Cache-Mapping-Simulator/client.cpp
// Function: main
int main()
{
    cache_mock Cacher;
    cout << "Cache-Mapper\n"
         << endl;
    cout << "Input only compatible values (such as power of 2s, etc)\n"
         << endl;
    long int d, c, m, b, s, l; // default meaning as in 'cache_mapper.cpp' constructor call;
    long int address;
    cout << "Enter 0 for Set-Associative, 1 for Direct-Map, 2 for Fully-Associative" << endl;
    cin >> d;
    cout << "Enter Cache-Size, Memory-Size, Block-Size in Bytes/Words (stick to one convention)" << endl;
    cin >> c >> m >> b;
    if (d != 1)
    {
        // There is no requirement of replacement techniques for direct mapped cache.
        cout << "Enter 1 for Least-Recently-Used, 0 for First-In-First-Out Hierarchy" << endl;
        cin >> l;
    }
    
    if (!d)
    {
        cout << "Enter X for X-way associative"<<endl;
        cin >> s;
        cache_mock temp(d, c, m, b, l, s);
        Cacher.cache_mock_copy(temp);
    }
    else
    {
        cache_mock temp(d, c, m, b, l);
        Cacher.cache_mock_copy(temp);
    }
    int flag = 1;
    int val;
    cout << "\n0 : Display\n1 : Load followed by address\n2 : Store followed by address" << endl;
    cout << "3 : Refresh dirty_bits\n4 : Clear cache main_frame\n5 : Exit\n" << endl;
    while (flag)
    {
        cout << "Input" << endl;
        cin >> val;
        switch (val)
        {
        case 0:
        {
            Cacher.container_display();
            cout << endl;
            break;
        }
        case 1:
        {
            cin >> address;
            int addressFlag = Cacher.loader(address);
            if (addressFlag == 1)
                cout << "Hit" << endl;
            else if(addressFlag == 0)
                cout << "Miss" << endl;
            else
            {
                cout << "Invalid address input" << endl;
            }
            
            break;
        }
        case 2:
        {
            cin >> address;
            if (Cacher.storer(address))
                cout << "Hit" << endl;
            else
                cout << "Miss" << endl;
            break;
        }
        case 3:
        {
            Cacher.refresh_dirty();
            break;
        }
        case 4:
        {
            Cacher.container_init();
            cout << "Cache was cleared!" << endl;
            break;
        }
        case 5:
        {
            flag--;
            break;
        }
        default:
        {
            cout << "\n0 : Display\n1 : Load followed by address\n2 : Store followed by address" << endl;
            cout << "3 : Refresh dirty_bits\n4 : Clear cache main_frame\n5 : Exit\n" << endl;   
        }
        }
        cout<<endl;
    }
    cout << "Simulation Terminated!" << endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movl $0x0, -0x4(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x1bd0
movq 0x8cde(%rip), %rdi      # 0x9fd0
leaq 0x4d23(%rip), %rsi      # 0x601c
callq 0x10c0
movq %rax, -0x158(%rbp)
jmp 0x1307
movq -0x158(%rbp), %rdi
movq 0x8cab(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x131c
movq 0x8cad(%rip), %rdi      # 0x9fd0
leaq 0x4d00(%rip), %rsi      # 0x602a
callq 0x10c0
movq %rax, -0x160(%rbp)
jmp 0x1338
movq -0x160(%rbp), %rdi
movq 0x8c7a(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x134d
movq 0x8c7c(%rip), %rdi      # 0x9fd0
leaq 0x4d08(%rip), %rsi      # 0x6063
callq 0x10c0
movq %rax, -0x168(%rbp)
jmp 0x1369
movq -0x168(%rbp), %rdi
movq 0x8c49(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x137e
movq 0x8c5b(%rip), %rdi      # 0x9fe0
leaq -0x70(%rbp), %rsi
callq 0x1080
jmp 0x1390
movq 0x8c39(%rip), %rdi      # 0x9fd0
leaq 0x4d0c(%rip), %rsi      # 0x60aa
callq 0x10c0
movq %rax, -0x170(%rbp)
jmp 0x13ac
movq -0x170(%rbp), %rdi
movq 0x8c06(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x13c1
movq 0x8c18(%rip), %rdi      # 0x9fe0
leaq -0x78(%rbp), %rsi
callq 0x1080
movq %rax, -0x178(%rbp)
jmp 0x13da
movq -0x178(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x1080
movq %rax, -0x180(%rbp)
jmp 0x13f3
movq -0x180(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x1080
jmp 0x1408
cmpq $0x1, -0x70(%rbp)
je 0x1468
movq 0x8bba(%rip), %rdi      # 0x9fd0
leaq 0x4ce0(%rip), %rsi      # 0x60fd
callq 0x10c0
movq %rax, -0x188(%rbp)
jmp 0x142b
movq -0x188(%rbp), %rdi
movq 0x8b87(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1440
movq 0x8b99(%rip), %rdi      # 0x9fe0
leaq -0x98(%rbp), %rsi
callq 0x1080
jmp 0x1455
jmp 0x1468
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
jmp 0x1967
cmpq $0x0, -0x70(%rbp)
jne 0x152e
movq 0x8b56(%rip), %rdi      # 0x9fd0
leaq 0x4cc0(%rip), %rsi      # 0x6141
callq 0x10c0
movq %rax, -0x190(%rbp)
jmp 0x148f
movq -0x190(%rbp), %rdi
movq 0x8b23(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x14a4
movq 0x8b35(%rip), %rdi      # 0x9fe0
leaq -0x90(%rbp), %rsi
callq 0x1080
jmp 0x14b9
movq -0x70(%rbp), %rsi
movq -0x78(%rbp), %rdx
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %r8
movq -0x98(%rbp), %r9
movq -0x90(%rbp), %rdi
movq %rsp, %rax
movq %rdi, (%rax)
leaq -0xf0(%rbp), %rdi
callq 0x1980
jmp 0x14ee
leaq -0x58(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x1c20
jmp 0x1500
leaq -0xf0(%rbp), %rdi
callq 0x1ca0
jmp 0x159d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x1ca0
jmp 0x1967
movq -0x70(%rbp), %rsi
movq -0x78(%rbp), %rdx
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %r8
movq -0x98(%rbp), %r9
movq %rsp, %rax
movq $0x0, (%rax)
leaq -0x140(%rbp), %rdi
callq 0x1980
jmp 0x1560
leaq -0x58(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x1c20
jmp 0x1572
leaq -0x140(%rbp), %rdi
callq 0x1ca0
jmp 0x159d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x1ca0
jmp 0x1967
movl $0x1, -0x144(%rbp)
movq 0x8a22(%rip), %rdi      # 0x9fd0
leaq 0x4baa(%rip), %rsi      # 0x615f
callq 0x10c0
movq %rax, -0x198(%rbp)
jmp 0x15c3
movq -0x198(%rbp), %rdi
movq 0x89ef(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x15d8
movq 0x89f1(%rip), %rdi      # 0x9fd0
leaq 0x4bc1(%rip), %rsi      # 0x61a7
callq 0x10c0
movq %rax, -0x1a0(%rbp)
jmp 0x15f4
movq -0x1a0(%rbp), %rdi
movq 0x89be(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1609
jmp 0x160b
cmpl $0x0, -0x144(%rbp)
je 0x1921
movq 0x89b1(%rip), %rdi      # 0x9fd0
leaq 0x4bbd(%rip), %rsi      # 0x61e3
callq 0x10c0
movq %rax, -0x1a8(%rbp)
jmp 0x1634
movq -0x1a8(%rbp), %rdi
movq 0x897e(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1649
movq 0x8990(%rip), %rdi      # 0x9fe0
leaq -0x148(%rbp), %rsi
callq 0x1090
jmp 0x165e
movl -0x148(%rbp), %eax
movq %rax, -0x1b0(%rbp)
subq $0x5, %rax
ja 0x18a3
movq -0x1b0(%rbp), %rax
leaq 0x4981(%rip), %rcx      # 0x6004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x58(%rbp), %rdi
callq 0x1cd0
jmp 0x1697
movq 0x8932(%rip), %rdi      # 0x9fd0
movq 0x891b(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x16ac
jmp 0x1907
movq 0x8928(%rip), %rdi      # 0x9fe0
leaq -0xa0(%rbp), %rsi
callq 0x1080
jmp 0x16c6
movq -0xa0(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x1e40
movq %rax, -0x1b8(%rbp)
jmp 0x16df
movq -0x1b8(%rbp), %rax
movl %eax, -0x14c(%rbp)
cmpl $0x1, -0x14c(%rbp)
jne 0x1728
movq 0x88d4(%rip), %rdi      # 0x9fd0
leaq 0x4ae6(%rip), %rsi      # 0x61e9
callq 0x10c0
movq %rax, -0x1c0(%rbp)
jmp 0x1711
movq -0x1c0(%rbp), %rdi
movq 0x88a1(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1726
jmp 0x1799
cmpl $0x0, -0x14c(%rbp)
jne 0x1764
movq 0x8898(%rip), %rdi      # 0x9fd0
leaq 0x4aae(%rip), %rsi      # 0x61ed
callq 0x10c0
movq %rax, -0x1c8(%rbp)
jmp 0x174d
movq -0x1c8(%rbp), %rdi
movq 0x8865(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1762
jmp 0x1797
movq 0x8865(%rip), %rdi      # 0x9fd0
leaq 0x4a80(%rip), %rsi      # 0x61f2
callq 0x10c0
movq %rax, -0x1d0(%rbp)
jmp 0x1780
movq -0x1d0(%rbp), %rdi
movq 0x8832(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1795
jmp 0x1797
jmp 0x1799
jmp 0x1907
movq 0x883b(%rip), %rdi      # 0x9fe0
leaq -0xa0(%rbp), %rsi
callq 0x1080
jmp 0x17b3
movq -0xa0(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x22a0
movq %rax, -0x1d8(%rbp)
jmp 0x17cc
movq -0x1d8(%rbp), %rax
cmpq $0x0, %rax
je 0x180c
movq 0x87f0(%rip), %rdi      # 0x9fd0
leaq 0x4a02(%rip), %rsi      # 0x61e9
callq 0x10c0
movq %rax, -0x1e0(%rbp)
jmp 0x17f5
movq -0x1e0(%rbp), %rdi
movq 0x87bd(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x180a
jmp 0x183f
movq 0x87bd(%rip), %rdi      # 0x9fd0
leaq 0x49d3(%rip), %rsi      # 0x61ed
callq 0x10c0
movq %rax, -0x1e8(%rbp)
jmp 0x1828
movq -0x1e8(%rbp), %rdi
movq 0x878a(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x183d
jmp 0x183f
jmp 0x1907
leaq -0x58(%rbp), %rdi
callq 0x2590
jmp 0x184f
jmp 0x1907
leaq -0x58(%rbp), %rdi
callq 0x1a70
jmp 0x185f
movq 0x876a(%rip), %rdi      # 0x9fd0
leaq 0x499b(%rip), %rsi      # 0x6208
callq 0x10c0
movq %rax, -0x1f0(%rbp)
jmp 0x187b
movq -0x1f0(%rbp), %rdi
movq 0x8737(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1890
jmp 0x1907
movl -0x144(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x144(%rbp)
jmp 0x1907
movq 0x8726(%rip), %rdi      # 0x9fd0
leaq 0x48ae(%rip), %rsi      # 0x615f
callq 0x10c0
movq %rax, -0x1f8(%rbp)
jmp 0x18bf
movq -0x1f8(%rbp), %rdi
movq 0x86f3(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x18d4
movq 0x86f5(%rip), %rdi      # 0x9fd0
leaq 0x48c5(%rip), %rsi      # 0x61a7
callq 0x10c0
movq %rax, -0x200(%rbp)
jmp 0x18f0
movq -0x200(%rbp), %rdi
movq 0x86c2(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1905
jmp 0x1907
movq 0x86c2(%rip), %rdi      # 0x9fd0
movq 0x86ab(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x191c
jmp 0x160b
movq 0x86a8(%rip), %rdi      # 0x9fd0
leaq 0x48ec(%rip), %rsi      # 0x621b
callq 0x10c0
movq %rax, -0x208(%rbp)
jmp 0x193d
movq -0x208(%rbp), %rdi
movq 0x8675(%rip), %rsi      # 0x9fc0
callq 0x10f0
jmp 0x1952
leaq -0x58(%rbp), %rdi
callq 0x1ca0
movl -0x4(%rbp), %eax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
leaq -0x58(%rbp), %rdi
callq 0x1ca0
movq -0x60(%rbp), %rdi
callq 0x1140
nopl (%rax)