// File: /workspace/github_cpp_makefile_star2_O3/saumya-prakash[P]AssemblerEmulator/emu.cpp
// Function: main
int main(int argc, char** argv)
{
    cout<<unitbuf;
    cin.tie(&cout);

    if(argc==1)
    {
        cout<<"No input file specified"<<endl;
        return EXIT_FAILURE;
    }

    Emulator e1(argv[1]);

    int loading = e1.loader();

    if(loading)
        cout<<"Object file loaded successfully"<<endl<<endl;
    
    else
    {
        cout<<"Error in loading object file"<<endl;
        cout<<"Process terminated"<<endl;
        return EXIT_FAILURE;
    }

    print_options();
    cout<<endl;

    char c;     // interact with the user
    do
    {
        cin>>c;

        switch(c)
        {
            case 'a':       // execute all instructions in one go
                        if(e1.get_program_status()==-1)     // program in fault state
                        {
                            cout<<e1.get_fault_cause()<<endl<<endl;
                            break;
                        }

                        if(e1.get_program_status()==0)
                        {
                            cout<<"Program finished execution"<<endl<<endl;
                            break;
                        }
                        
                        while(e1.get_program_status()==1)
                            e1.execute();
                        
                        if(e1.get_program_status()==-1)     // program in fault state after completing execution
                        {
                            cout<<e1.get_fault_cause()<<endl<<endl;
                            break;
                        }

                        cout<<"Total instructions executed = "<<e1.instructions_executed()<<endl;
                        cout<<endl;
                        break;


            case 't':       // execute a single instruction with trace
                        if(e1.get_program_status()==-1)
                        {
                            cout<<e1.get_fault_cause()<<endl;
                            cout<<endl;
                            break;
                        }

                        if(e1.get_program_status()==0)
                        {   cout<<"Program finished execution"<<endl;
                            cout<<endl;
                            break;
                        }

                        cout<<e1.execute()<<endl;
                        cout<<endl;
                        break;

            case 's':   // execute all instrutions with trace
                        if(e1.get_program_status()==-1)     // program in fault state
                        {
                            cout<<e1.get_fault_cause()<<endl<<endl;
                            break;
                        }

                        if(e1.get_program_status()==0)
                        {
                            cout<<"Program finished execution"<<endl<<endl;
                            break;
                        }
                        

                        while(e1.get_program_status()==1)
                            cout<<e1.execute()<<endl;
                        cout<<endl;
                
                        cout<<"Total instructions executed = "<<e1.instructions_executed()<<endl;
                        cout<<endl;
                        break;


            case 'n':       // print specified number of instructions
                        {
                            int a = 0;
                            cin>>a;
                            int i = 0;
                            while(i<a && e1.get_program_status()==1)
                            {
                                i++;
                                cout<<e1.execute()<<endl;
                            }
                            cout<<endl;
                        }
                        
                        break;

            case 'q':       // show current architectural state
                        cout<<e1.current_state()<<endl;
                        cout<<endl;
                        break;
                        

            case 'u':       // disassemble
                        e1.disassemble(cout);
                        cout<<endl;
                        break;



            case 'd':       // outputs memory dump
                        e1.memory_dump(cout);
                        break; 


            case 'c':   // number of instructions executed thus far
                        cout<<"Number of instructions executed = "<<e1.instructions_executed()<<endl;
                        cout<<endl;
                        break;

            case 'x':       // QUIT
                        cout<<"Emulation terminated"<<endl;
                        cout<<endl;
                        break;

                        
            default:    cout<<"Invalid option"<<endl;
                        print_options();
                        cout<<endl;

                        continue;
                        break;
        }


    } while (c!='x');
    

    cout<<nounitbuf;
    return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq 0x67f5(%rip), %rbx      # 0x9fd0
movq (%rbx), %rax
movq -0x18(%rax), %rax
orl $0x2000, 0x18(%rbx,%rax) # imm = 0x2000
movq 0x67ef(%rip), %rax      # 0x9fe0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq %rbx, 0xd8(%rax,%rcx)
cmpl $0x1, %edi
jne 0x384a
leaq 0x3977(%rip), %rsi      # 0x7183
movl $0x17, %edx
movq %rbx, %rdi
callq 0x21b0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x1, %ebx
jmp 0x4188
movq 0x8(%rsi), %rsi
leaq 0x8(%rsp), %rdi
leaq 0x2c(%rsp), %rdx
callq 0x421c
leaq 0x30(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x425a
leaq 0x18(%rsp), %rbp
movq -0x10(%rbp), %rdi
cmpq %rbp, %rdi
je 0x3887
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x30(%rsp), %rdi
callq 0x444c
testb %al, %al
je 0x40d3
movq 0x6730(%rip), %rbx      # 0x9fd0
leaq 0x38f4(%rip), %rsi      # 0x719b
movl $0x1f, %edx
movq %rbx, %rdi
callq 0x21b0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq 0x66fe(%rip), %rbx      # 0x9fd0
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
callq 0x356c
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq 0x66a1(%rip), %r15      # 0x9fd0
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x30(%rsp), %r12
leaq 0x8(%rsp), %r13
movq 0x6690(%rip), %rdi      # 0x9fe0
leaq 0x7(%rsp), %rsi
callq 0x21f0
movzbl 0x7(%rsp), %eax
cmpl $0x6d, %eax
jle 0x3a48
addl $-0x6e, %eax
cmpl $0xa, %eax
ja 0x3ca4
leaq 0x3689(%rip), %rcx      # 0x7004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, 0x2c(%rsp)
movq 0x664d(%rip), %rdi      # 0x9fe0
leaq 0x2c(%rsp), %rsi
callq 0x20f0
cmpl $0x0, 0x2c(%rsp)
jle 0x3a1c
xorl %r14d, %r14d
movq %r12, %rdi
callq 0x57f0
cmpl $0x1, %eax
jne 0x3a1c
movq %r13, %rdi
movq %r12, %rsi
callq 0x4780
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x3a12
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
incl %r14d
cmpl 0x2c(%rsp), %r14d
jl 0x39a7
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x3ed3
cmpl $0x61, %eax
je 0x3bfe
cmpl $0x63, %eax
je 0x3c67
cmpl $0x64, %eax
jne 0x3ca4
movq %r12, %rdi
movq %r15, %rsi
callq 0x5be4
jmp 0x3ed3
movq %r12, %rdi
movq %r15, %rsi
callq 0x5966
jmp 0x3ea9
movq %r12, %rdi
callq 0x57f0
cmpl $-0x1, %eax
je 0x3dab
movq %r12, %rdi
callq 0x57f0
testl %eax, %eax
je 0x3f6e
movq %r12, %rdi
callq 0x57f0
cmpl $0x1, %eax
jne 0x3ce9
movq %r13, %rdi
movq %r12, %rsi
callq 0x4780
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x3aa4
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3aa4
movq %r12, %rdi
callq 0x57f0
cmpl $-0x1, %eax
je 0x3e36
movq %r12, %rdi
callq 0x57f0
testl %eax, %eax
je 0x3fc5
movq %r13, %rdi
movq %r12, %rsi
callq 0x4780
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x3e92
movq %r13, %rdi
movq %r12, %rsi
callq 0x4e0c
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x3e92
movl $0x14, %edx
leaq 0x366e(%rip), %rsi      # 0x7248
movq %r15, %rdi
callq 0x21b0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movq %r15, %rbx
jmp 0x3d93
movq %r12, %rdi
callq 0x57f0
cmpl $-0x1, %eax
je 0x3ee3
movq %r12, %rdi
callq 0x57f0
testl %eax, %eax
je 0x3fd6
movq %r12, %rdi
callq 0x57f0
cmpl $0x1, %eax
jne 0x3d4a
leaq 0xa8(%rsp), %rdi
movq %r12, %rsi
callq 0x4780
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x3c1f
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3c1f
movl $0x22, %edx
movq %r15, %rdi
leaq 0x35af(%rip), %rsi      # 0x7225
callq 0x21b0
movq 0x70(%rsp), %rsi
movq %r15, %rdi
callq 0x2100
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
jmp 0x3d93
movl $0xe, %edx
movq %r15, %rdi
leaq 0x35aa(%rip), %rsi      # 0x725d
callq 0x21b0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
callq 0x356c
jmp 0x3ea9
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x1e, %edx
movq %r15, %rdi
leaq 0x34e7(%rip), %rsi      # 0x7206
callq 0x21b0
movq 0x70(%rsp), %rsi
movq %r15, %rdi
callq 0x2100
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
jmp 0x3d93
movq %r12, %rdi
callq 0x57f0
cmpl $-0x1, %eax
je 0x402d
movl $0x1e, %edx
movq %r15, %rdi
leaq 0x349c(%rip), %rsi      # 0x7206
callq 0x21b0
movq 0x70(%rsp), %rsi
movq %r15, %rdi
callq 0x2100
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x3ea9
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x431c
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x40b3
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x431c
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x3ea9
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movq %r15, %rbx
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
cmpb $0x78, 0x7(%rsp)
jne 0x3949
jmp 0x4166
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x431c
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
jmp 0x40b3
movl $0x1a, %edx
movq %r15, %rdi
leaq 0x326e(%rip), %rsi      # 0x71eb
callq 0x21b0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
jmp 0x3ec0
movl $0x1a, %edx
leaq 0x321a(%rip), %rsi      # 0x71eb
jmp 0x3bda
movl $0x1a, %edx
movq %r15, %rdi
leaq 0x3206(%rip), %rsi      # 0x71eb
callq 0x21b0
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
jmp 0x3ec0
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x431c
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq %r15, %rdi
callq 0x21b0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x3ed3
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3ed3
movq 0x5ef6(%rip), %rbx      # 0x9fd0
leaq 0x30da(%rip), %rsi      # 0x71bb
movl $0x1c, %edx
movq %rbx, %rdi
callq 0x21b0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq 0x5ec4(%rip), %rdi      # 0x9fd0
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x5eb0(%rip), %rbx      # 0x9fd0
leaq 0x30b1(%rip), %rsi      # 0x71d8
movl $0x12, %edx
movq %rbx, %rdi
callq 0x21b0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq 0x5e7e(%rip), %rdi      # 0x9fd0
callq 0x2040
movl $0x1, %ebx
movq %rax, %rdi
callq 0x2120
jmp 0x417e
movq 0x5e63(%rip), %rax      # 0x9fd0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
andl $0xffffdfff, 0x18(%rax,%rcx) # imm = 0xFFFFDFFF
xorl %ebx, %ebx
leaq 0x30(%rsp), %rdi
callq 0x42d8
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x4207
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x4214
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4214
movq %rax, %rbx
jmp 0x4214
jmp 0x4207
jmp 0x4207
jmp 0x41eb
jmp 0x41eb
jmp 0x41eb
jmp 0x41eb
jmp 0x41eb
jmp 0x4207
jmp 0x41eb
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x4207
jmp 0x41eb
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x420a
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x420a
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x42d8
movq %rbx, %rdi
callq 0x2270