// File: ariannagavioli[P]ALU/simulator.cpp
// Function: main
int main() {
	System system;
	
	//Initialize the system here by adding modules to the system object
	// system.addModule(new ExampleModule("Alice"));
	// system.addModule(new ExampleModule("Bob", 10));//The second parameter is the priority. It's useful only when you need to intercept someone's else message
	uint8_t dst = 4;
	
	global_regs.general_regs[dst] = -4000;
	cout << "Initial binary " << bitset<16>(global_regs.general_regs[dst]) << endl;

	alu_regs.opcode = IMUL_OPC;
	alu_regs.operand1 = 2;

	global_regs.general_regs[alu_regs.operand1] = 5;
	
	alu_regs.operand2 = dst;
	alu_regs.destination_reg = dst;

	cout << "OPCODE: " << int(alu_regs.opcode) << 
	" / OPE1: " << alu_regs.operand1 <<
	" / OPE2: " << alu_regs.operand2 << 
	" / DST: " << int(alu_regs.destination_reg) << 
	" / GENR: " << global_regs.general_regs[dst] << endl; 

	system.addModule(new AluModule("Alu"));
	system.addModule(new ExampleModule("Fetch"));
	//Call run() to start the simulation
	system.run();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
leaq -0x40(%rbp), %rdi
callq 0x8fc0
movb $0x4, -0x41(%rbp)
movzbl -0x41(%rbp), %eax
movl %eax, %ecx
leaq 0x558f(%rip), %rax      # 0xe164
movw $0xf060, 0x2(%rax,%rcx,2) # imm = 0xF060
movq 0x53f5(%rip), %rdi      # 0xdfd8
leaq 0x15b0(%rip), %rsi      # 0xa19a
callq 0x2170
movq %rax, -0xb8(%rbp)
jmp 0x8bf8
movzbl -0x41(%rbp), %eax
movl %eax, %ecx
leaq 0x555f(%rip), %rax      # 0xe164
movzwl 0x2(%rax,%rcx,2), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
movq %rdi, -0xc8(%rbp)
callq 0x4450
movq -0xb8(%rbp), %rdi
movq -0xc8(%rbp), %rsi
callq 0x4350
movq %rax, -0xc0(%rbp)
jmp 0x8c38
movq -0xc0(%rbp), %rdi
movq 0x5382(%rip), %rsi      # 0xdfc8
callq 0x2190
jmp 0x8c4d
leaq 0x5508(%rip), %rax      # 0xe15c
movb $0x65, (%rax)
movw $0x2, 0x2(%rax)
movzwl 0x2(%rax), %ecx
movl %ecx, %edx
leaq 0x54fa(%rip), %rcx      # 0xe164
movw $0x5, 0x2(%rcx,%rdx,2)
movzbl -0x41(%rbp), %ecx
movw %cx, 0x4(%rax)
movb -0x41(%rbp), %cl
movb %cl, 0x6(%rax)
movq 0x5352(%rip), %rdi      # 0xdfd8
leaq 0x151d(%rip), %rsi      # 0xa1aa
callq 0x2170
movq %rax, -0xd0(%rbp)
jmp 0x8c9b
movq -0xd0(%rbp), %rdi
leaq 0x54b3(%rip), %rax      # 0xe15c
movzbl (%rax), %esi
callq 0x2230
movq %rax, -0xd8(%rbp)
jmp 0x8cba
movq -0xd8(%rbp), %rdi
leaq 0x14eb(%rip), %rsi      # 0xa1b3
callq 0x2170
movq %rax, -0xe0(%rbp)
jmp 0x8cd6
movq -0xe0(%rbp), %rdi
leaq 0x5478(%rip), %rax      # 0xe15c
movzwl 0x2(%rax), %esi
callq 0x2220
movq %rax, -0xe8(%rbp)
jmp 0x8cf6
movq -0xe8(%rbp), %rdi
leaq 0x14b9(%rip), %rsi      # 0xa1bd
callq 0x2170
movq %rax, -0xf0(%rbp)
jmp 0x8d12
movq -0xf0(%rbp), %rdi
leaq 0x543c(%rip), %rax      # 0xe15c
movzwl 0x4(%rax), %esi
callq 0x2220
movq %rax, -0xf8(%rbp)
jmp 0x8d32
movq -0xf8(%rbp), %rdi
leaq 0x1487(%rip), %rsi      # 0xa1c7
callq 0x2170
movq %rax, -0x100(%rbp)
jmp 0x8d4e
movq -0x100(%rbp), %rdi
leaq 0x5400(%rip), %rax      # 0xe15c
movzbl 0x6(%rax), %esi
callq 0x2230
movq %rax, -0x108(%rbp)
jmp 0x8d6e
movq -0x108(%rbp), %rdi
leaq 0x1454(%rip), %rsi      # 0xa1d0
callq 0x2170
movq %rax, -0x110(%rbp)
jmp 0x8d8a
movq -0x110(%rbp), %rdi
movzbl -0x41(%rbp), %eax
movl %eax, %ecx
leaq 0x53c6(%rip), %rax      # 0xe164
movzwl 0x2(%rax,%rcx,2), %esi
callq 0x2220
movq %rax, -0x118(%rbp)
jmp 0x8db1
movq -0x118(%rbp), %rdi
movq 0x5209(%rip), %rsi      # 0xdfc8
callq 0x2190
jmp 0x8dc6
movl $0x68, %edi
callq 0x2180
movq %rax, -0x120(%rbp)
jmp 0x8dd9
movb $0x1, -0x82(%rbp)
leaq -0x81(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x2260
movq -0x128(%rbp), %rdx
leaq 0x12fe(%rip), %rsi      # 0xa0ff
leaq -0x80(%rbp), %rdi
callq 0x21d0
jmp 0x8e0c
movq -0x120(%rbp), %rdi
leaq -0x80(%rbp), %rsi
xorl %edx, %edx
callq 0x2440
jmp 0x8e20
movq -0x120(%rbp), %rsi
movb $0x0, -0x82(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4f30
jmp 0x8e39
leaq -0x80(%rbp), %rdi
callq 0x20e0
leaq -0x81(%rbp), %rdi
callq 0x21a0
movl $0x48, %edi
callq 0x2180
movq %rax, -0x130(%rbp)
jmp 0x8e61
movb $0x1, -0xaa(%rbp)
leaq -0xa9(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x2260
movq -0x138(%rbp), %rdx
leaq 0x127a(%rip), %rsi      # 0xa103
leaq -0xa8(%rbp), %rdi
callq 0x21d0
jmp 0x8e97
movq -0x130(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
xorl %edx, %edx
callq 0x4970
jmp 0x8eae
movq -0x130(%rbp), %rsi
movb $0x0, -0xaa(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4f30
jmp 0x8ec7
leaq -0xa8(%rbp), %rdi
callq 0x20e0
leaq -0xa9(%rbp), %rdi
callq 0x21a0
leaq -0x40(%rbp), %rdi
callq 0x5170
jmp 0x8eea
leaq -0x40(%rbp), %rdi
callq 0x9020
xorl %eax, %eax
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x8fa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x8f32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x20e0
leaq -0x81(%rbp), %rdi
callq 0x21a0
testb $0x1, -0x82(%rbp)
jne 0x8f49
jmp 0x8f55
movq -0x120(%rbp), %rdi
callq 0x2160
jmp 0x8fa2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x8f7d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x20e0
leaq -0xa9(%rbp), %rdi
callq 0x21a0
testb $0x1, -0xaa(%rbp)
jne 0x8f94
jmp 0x8fa0
movq -0x130(%rbp), %rdi
callq 0x2160
jmp 0x8fa2
leaq -0x40(%rbp), %rdi
callq 0x9020
movq -0x50(%rbp), %rdi
callq 0x2250
nopw %cs:(%rax,%rax)
nop