// File: /workspace/github_cpp_makefile_star2_O1/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 0x67c5(%rip), %rbx      # 0x9fd0
movq (%rbx), %rax
movq -0x18(%rax), %rax
orl $0x2000, 0x18(%rbx,%rax) # imm = 0x2000
movq 0x67bf(%rip), %rax      # 0x9fe0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq %rbx, 0xd8(%rax,%rcx)
cmpl $0x1, %edi
jne 0x387a
leaq 0x3947(%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 0x41b8
movq 0x8(%rsi), %rsi
leaq 0x8(%rsp), %rdi
leaq 0x2c(%rsp), %rdx
callq 0x424c
leaq 0x30(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x428a
leaq 0x18(%rsp), %rbp
movq -0x10(%rbp), %rdi
cmpq %rbp, %rdi
je 0x38b7
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x30(%rsp), %rdi
callq 0x4470
testb %al, %al
je 0x4103
movq 0x6700(%rip), %rbx      # 0x9fd0
leaq 0x38c4(%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 0x66ce(%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 0x359c
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2170
movsbl %al, %esi
movq 0x6671(%rip), %r15      # 0x9fd0
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x30(%rsp), %r12
leaq 0x8(%rsp), %r13
movq 0x6660(%rip), %rdi      # 0x9fe0
leaq 0x7(%rsp), %rsi
callq 0x21f0
movzbl 0x7(%rsp), %eax
cmpl $0x6d, %eax
jle 0x3a78
addl $-0x6e, %eax
cmpl $0xa, %eax
ja 0x3cd4
leaq 0x3659(%rip), %rcx      # 0x7004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x0, 0x2c(%rsp)
movq 0x661d(%rip), %rdi      # 0x9fe0
leaq 0x2c(%rsp), %rsi
callq 0x20f0
cmpl $0x0, 0x2c(%rsp)
jle 0x3a4c
xorl %r14d, %r14d
movq %r12, %rdi
callq 0x57e2
cmpl $0x1, %eax
jne 0x3a4c
movq %r13, %rdi
movq %r12, %rsi
callq 0x479a
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 0x3a42
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
incl %r14d
cmpl 0x2c(%rsp), %r14d
jl 0x39d7
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 0x3f03
cmpl $0x61, %eax
je 0x3c2e
cmpl $0x63, %eax
je 0x3c97
cmpl $0x64, %eax
jne 0x3cd4
movq %r12, %rdi
movq %r15, %rsi
callq 0x5bee
jmp 0x3f03
movq %r12, %rdi
movq %r15, %rsi
callq 0x5954
jmp 0x3ed9
movq %r12, %rdi
callq 0x57e2
cmpl $-0x1, %eax
je 0x3ddb
movq %r12, %rdi
callq 0x57e2
testl %eax, %eax
je 0x3f9e
movq %r12, %rdi
callq 0x57e2
cmpl $0x1, %eax
jne 0x3d19
movq %r13, %rdi
movq %r12, %rsi
callq 0x479a
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 0x3ad4
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3ad4
movq %r12, %rdi
callq 0x57e2
cmpl $-0x1, %eax
je 0x3e66
movq %r12, %rdi
callq 0x57e2
testl %eax, %eax
je 0x3ff5
movq %r13, %rdi
movq %r12, %rsi
callq 0x479a
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 0x3ec2
movq %r13, %rdi
movq %r12, %rsi
callq 0x4e0e
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 0x3ec2
movl $0x14, %edx
leaq 0x363e(%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 0x3dc3
movq %r12, %rdi
callq 0x57e2
cmpl $-0x1, %eax
je 0x3f13
movq %r12, %rdi
callq 0x57e2
testl %eax, %eax
je 0x4006
movq %r12, %rdi
callq 0x57e2
cmpl $0x1, %eax
jne 0x3d7a
leaq 0xa8(%rsp), %rdi
movq %r12, %rsi
callq 0x479a
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x3c4f
movq 0xb8(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3c4f
movl $0x22, %edx
movq %r15, %rdi
leaq 0x357f(%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 0x3dc3
movl $0xe, %edx
movq %r15, %rdi
leaq 0x357a(%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 0x359c
jmp 0x3ed9
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 0x34b7(%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 0x3dc3
movq %r12, %rdi
callq 0x57e2
cmpl $-0x1, %eax
je 0x405d
movl $0x1e, %edx
movq %r15, %rdi
leaq 0x346c(%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 0x3ed9
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x434c
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 0x40e3
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x434c
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 0x3ed9
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 0x3979
jmp 0x4196
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x434c
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 0x40e3
movl $0x1a, %edx
movq %r15, %rdi
leaq 0x323e(%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 0x3ef0
movl $0x1a, %edx
leaq 0x31ea(%rip), %rsi      # 0x71eb
jmp 0x3c0a
movl $0x1a, %edx
movq %r15, %rdi
leaq 0x31d6(%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 0x3ef0
movq %rbp, 0x8(%rsp)
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
addq %rsi, %rdx
movq %r13, %rdi
callq 0x434c
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 0x3f03
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x3f03
movq 0x5ec6(%rip), %rbx      # 0x9fd0
leaq 0x30aa(%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 0x5e94(%rip), %rdi      # 0x9fd0
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq 0x5e80(%rip), %rbx      # 0x9fd0
leaq 0x3081(%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 0x5e4e(%rip), %rdi      # 0x9fd0
callq 0x2040
movl $0x1, %ebx
movq %rax, %rdi
callq 0x2120
jmp 0x41ae
movq 0x5e33(%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 0x4308
movl %ebx, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x4237
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x4244
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4244
movq %rax, %rbx
jmp 0x4244
jmp 0x4237
jmp 0x4237
jmp 0x421b
jmp 0x421b
jmp 0x421b
jmp 0x421b
jmp 0x421b
jmp 0x4237
jmp 0x421b
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x4237
jmp 0x421b
movq %rax, %rbx
movq 0x8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x423a
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x423a
movq %rax, %rbx
leaq 0x30(%rsp), %rdi
callq 0x4308
movq %rbx, %rdi
callq 0x2270