// File: tmtxt[P]microcontroller-emulation/macrochippic32f42.cpp
// Function: mcontroller::MacrochipPIC32F42::executeBranchIfNotEqual(int)
void MacrochipPIC32F42::executeBranchIfNotEqual(int address){

		if((address + 4) < this->getMemorySize()){
					
			// the value to compare
			unsigned char comparisonValue = this->getMemoryValueAtLocation(address + 1);
		
			// compare W to comparisonValue
			if(comparisonValue == this->getW()){
				// if equal, set the program counter to the 4 block of memory after
				// the opcode
				this->setProgramCounter(address + 4);

				cout << "Message: Execution completed." << endl;
				
			} else {
				// get the high byte and low byte address of the destination address
				unsigned char addressHighByte = this->getMemoryValueAtLocation(address + 2);
				unsigned char addressLowByte = this->getMemoryValueAtLocation(address + 3);

				// compute the destination address
				int destinationAddress = (addressHighByte << 8) | addressLowByte;

				if(destinationAddress >= 0 && destinationAddress < this->getMemorySize()){
					
					// set the program counter to the new address
					this->setProgramCounter(destinationAddress);
					cout << "Message: Execution completed." << endl;
				} else {
					cerr << "Error: Invalid memory address" << endl;
					this->executeHalt(address);
				}

			}
		} else {
			cerr << "Error: SIGWEED. Program executed past top of memory" << endl;
			this->executeHalt(address);
		}

	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x20(%rbp)
movl -0xc(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x18(%rbp)
callq 0x4d90
movl %eax, %ecx
movl -0x18(%rbp), %eax
cmpl %ecx, %eax
jge 0x5bda
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
addl $0x1, %esi
callq 0x4df0
movq -0x20(%rbp), %rdi
movb %al, -0xd(%rbp)
movzbl -0xd(%rbp), %eax
movl %eax, -0x24(%rbp)
callq 0x53f0
movb %al, %cl
movl -0x24(%rbp), %eax
movzbl %cl, %ecx
cmpl %ecx, %eax
jne 0x5b26
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
addl $0x4, %esi
callq 0x4dd0
movq 0x94c2(%rip), %rdi      # 0xefc8
leaq 0x4b9f(%rip), %rsi      # 0xa6ac
callq 0x31e0
movq %rax, %rdi
movq 0x949c(%rip), %rsi      # 0xefb8
callq 0x3220
jmp 0x5bd8
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
addl $0x2, %esi
callq 0x4df0
movq -0x20(%rbp), %rdi
movb %al, -0xe(%rbp)
movl -0xc(%rbp), %esi
addl $0x3, %esi
callq 0x4df0
movb %al, -0xf(%rbp)
movzbl -0xe(%rbp), %eax
shll $0x8, %eax
movzbl -0xf(%rbp), %ecx
orl %ecx, %eax
movl %eax, -0x14(%rbp)
cmpl $0x0, -0x14(%rbp)
jl 0x5ba8
movq -0x20(%rbp), %rdi
movl -0x14(%rbp), %eax
movl %eax, -0x28(%rbp)
callq 0x4d90
movl %eax, %ecx
movl -0x28(%rbp), %eax
cmpl %ecx, %eax
jge 0x5ba8
movq -0x20(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x4dd0
movq 0x943d(%rip), %rdi      # 0xefc8
leaq 0x4b1a(%rip), %rsi      # 0xa6ac
callq 0x31e0
movq %rax, %rdi
movq 0x9417(%rip), %rsi      # 0xefb8
callq 0x3220
jmp 0x5bd6
movq 0x9441(%rip), %rdi      # 0xeff0
leaq 0x4b67(%rip), %rsi      # 0xa71d
callq 0x31e0
movq %rax, %rdi
movq 0x93f3(%rip), %rsi      # 0xefb8
callq 0x3220
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x5c10
jmp 0x5bd8
jmp 0x5c08
movq 0x940f(%rip), %rdi      # 0xeff0
leaq 0x4ae2(%rip), %rsi      # 0xa6ca
callq 0x31e0
movq %rax, %rdi
movq 0x93c1(%rip), %rsi      # 0xefb8
callq 0x3220
movq -0x20(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x5c10
addq $0x30, %rsp
popq %rbp
retq
nop