// File: ys1998[P]spsim/src/alu.cpp
// Function: ALU1::operate()
void ALU1::operate(void){
	int funct = std::get<1>(i.type());
	int opcode = std::get<0>(i.type());
	if(funct == FUNCT["add"]){
		res = in1 + in2;
	}else if(funct == FUNCT["sub"]){
		res = in1 - in2;
	}else if(opcode != 0){
		if ((opcode == OPCODE["beq"]) || (opcode == OPCODE["bne"]))	{	
			if(opcode == OPCODE["beq"]){
				res = (in1 == in2);
			}else if(opcode == OPCODE["bne"]){
				res = (in1 != in2);
			}
			// Branch prediction update
			int possible_jump_address = i.get_pc() + 1 + i.get_immediate();
			*(predict_addr + i.get_pc() % BRANCH_PREDICT_SLOTS) = possible_jump_address;
			
			if(res == 1){
				*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) += 1;
				if(*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) == STRONGLY_TAKEN + 1)
					*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) = STRONGLY_TAKEN;
			}else{
				*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) -= 1;
				if(*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) == STRONGLY_NOT_TAKEN - 1)
					*(predict + i.get_pc() % BRANCH_PREDICT_SLOTS) = STRONGLY_NOT_TAKEN;
			}
			
			if (res != i.predicted || ((res == 1) && (possible_jump_address != i.jumpAddressPred))){
				//	case of misprediction
				if(res == 0) possible_jump_address = i.get_pc()+1;
				// flush second ALU
				a->flush(i.get_id());
				a3->flush(i.get_id());
				// flush other entities
				f->flush(i.get_id(), possible_jump_address);
			}
				
		}	
	} 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x260, %rsp            # imm = 0x260
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rsi
movq %rsi, -0x150(%rbp)
addq $0x8, %rsi
movq %rsi, -0x140(%rbp)
leaq -0x14(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x105b0
movq -0x148(%rbp), %rdi
callq 0x61f0
movq -0x140(%rbp), %rsi
movl (%rax), %eax
movl %eax, -0xc(%rbp)
leaq -0x20(%rbp), %rdi
movq %rdi, -0x138(%rbp)
callq 0x105b0
movq -0x138(%rbp), %rdi
callq 0x6210
movl (%rax), %eax
movl %eax, -0x18(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x12c(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0x128(%rbp)
callq 0x3490
movq -0x128(%rbp), %rdx
leaq 0x1e30f(%rip), %rsi     # 0x22004
leaq -0x40(%rbp), %rdi
callq 0x6020
jmp 0x3d00
leaq 0x2b5f1(%rip), %rdi     # 0x2f2f8
leaq -0x40(%rbp), %rsi
callq 0x5f40
movq %rax, -0x158(%rbp)
jmp 0x3d19
movq -0x158(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x15c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x31e0
leaq -0x41(%rbp), %rdi
callq 0x3300
movl -0x15c(%rbp), %ecx
movl -0x12c(%rbp), %eax
cmpl %ecx, %eax
jne 0x3d99
movq -0x150(%rbp), %rax
movl 0xb4(%rax), %ecx
addl 0xb8(%rax), %ecx
movl %ecx, 0xbc(%rax)
jmp 0x44fc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x3d8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x31e0
leaq -0x41(%rbp), %rdi
callq 0x3300
jmp 0x4505
movl -0xc(%rbp), %eax
movl %eax, -0x16c(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x3490
movq -0x168(%rbp), %rdx
leaq 0x1e248(%rip), %rsi     # 0x22008
leaq -0x78(%rbp), %rdi
callq 0x6020
jmp 0x3dcb
leaq 0x2b526(%rip), %rdi     # 0x2f2f8
leaq -0x78(%rbp), %rsi
callq 0x5f40
movq %rax, -0x178(%rbp)
jmp 0x3de4
movq -0x178(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x17c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x31e0
leaq -0x79(%rbp), %rdi
callq 0x3300
movl -0x17c(%rbp), %ecx
movl -0x16c(%rbp), %eax
cmpl %ecx, %eax
jne 0x3e64
movq -0x150(%rbp), %rax
movl 0xb4(%rax), %ecx
subl 0xb8(%rax), %ecx
movl %ecx, 0xbc(%rax)
jmp 0x44fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x3e56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x31e0
leaq -0x79(%rbp), %rdi
callq 0x3300
jmp 0x4505
cmpl $0x0, -0x18(%rbp)
je 0x44f8
movl -0x18(%rbp), %eax
movl %eax, -0x18c(%rbp)
leaq -0xa1(%rbp), %rdi
movq %rdi, -0x188(%rbp)
callq 0x3490
movq -0x188(%rbp), %rdx
movb $0x0, -0xca(%rbp)
movb $0x0, -0xcb(%rbp)
leaq 0x1e166(%rip), %rsi     # 0x2200c
leaq -0xa0(%rbp), %rdi
callq 0x6020
jmp 0x3eb4
leaq 0x2b40d(%rip), %rdi     # 0x2f2c8
leaq -0xa0(%rbp), %rsi
callq 0x5f40
movq %rax, -0x198(%rbp)
jmp 0x3ed0
movl -0x18c(%rbp), %ecx
movq -0x198(%rbp), %rdx
movb $0x1, %al
cmpl (%rdx), %ecx
movb %al, -0x199(%rbp)
je 0x3f63
movl -0x18(%rbp), %eax
movl %eax, -0x1ac(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x1a8(%rbp)
callq 0x3490
movq -0x1a8(%rbp), %rdx
movb $0x1, -0xca(%rbp)
leaq 0x1e0f6(%rip), %rsi     # 0x22010
leaq -0xc8(%rbp), %rdi
callq 0x6020
jmp 0x3f28
movb $0x1, -0xcb(%rbp)
leaq 0x2b392(%rip), %rdi     # 0x2f2c8
leaq -0xc8(%rbp), %rsi
callq 0x5f40
movq %rax, -0x1b8(%rbp)
jmp 0x3f4b
movl -0x1ac(%rbp), %eax
movq -0x1b8(%rbp), %rcx
cmpl (%rcx), %eax
sete %al
movb %al, -0x199(%rbp)
movb -0x199(%rbp), %al
movb %al, -0x1b9(%rbp)
testb $0x1, -0xcb(%rbp)
jne 0x3f7a
jmp 0x3f86
leaq -0xc8(%rbp), %rdi
callq 0x31e0
testb $0x1, -0xca(%rbp)
jne 0x3f91
jmp 0x3f9d
leaq -0xc9(%rbp), %rdi
callq 0x3300
leaq -0xa0(%rbp), %rdi
callq 0x31e0
leaq -0xa1(%rbp), %rdi
callq 0x3300
movb -0x1b9(%rbp), %al
testb $0x1, %al
jne 0x3fc4
jmp 0x44f6
movl -0x18(%rbp), %eax
movl %eax, -0x1cc(%rbp)
leaq -0xf1(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x3490
movq -0x1c8(%rbp), %rdx
leaq 0x1e01e(%rip), %rsi     # 0x2200c
leaq -0xf0(%rbp), %rdi
callq 0x6020
jmp 0x3ffc
leaq 0x2b2c5(%rip), %rdi     # 0x2f2c8
leaq -0xf0(%rbp), %rsi
callq 0x5f40
movq %rax, -0x1d8(%rbp)
jmp 0x4018
movq -0x1d8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x1dc(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x31e0
leaq -0xf1(%rbp), %rdi
callq 0x3300
movl -0x1dc(%rbp), %ecx
movl -0x1cc(%rbp), %eax
cmpl %ecx, %eax
jne 0x4136
movq -0x150(%rbp), %rax
movl 0xb4(%rax), %ecx
cmpl 0xb8(%rax), %ecx
sete %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0xbc(%rax)
jmp 0x421e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x40ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x40e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x40c9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
testb $0x1, -0xcb(%rbp)
jne 0x40bb
jmp 0x40c7
leaq -0xc8(%rbp), %rdi
callq 0x31e0
jmp 0x40c9
testb $0x1, -0xca(%rbp)
jne 0x40d4
jmp 0x40e0
leaq -0xc9(%rbp), %rdi
callq 0x3300
jmp 0x40e2
leaq -0xa0(%rbp), %rdi
callq 0x31e0
leaq -0xa1(%rbp), %rdi
callq 0x3300
jmp 0x4505
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4125
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x31e0
leaq -0xf1(%rbp), %rdi
callq 0x3300
jmp 0x4505
movl -0x18(%rbp), %eax
movl %eax, -0x1ec(%rbp)
leaq -0x119(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x3490
movq -0x1e8(%rbp), %rdx
leaq 0x1deb0(%rip), %rsi     # 0x22010
leaq -0x118(%rbp), %rdi
callq 0x6020
jmp 0x416e
leaq 0x2b153(%rip), %rdi     # 0x2f2c8
leaq -0x118(%rbp), %rsi
callq 0x5f40
movq %rax, -0x1f8(%rbp)
jmp 0x418a
movq -0x1f8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x1fc(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x31e0
leaq -0x119(%rbp), %rdi
callq 0x3300
movl -0x1fc(%rbp), %ecx
movl -0x1ec(%rbp), %eax
cmpl %ecx, %eax
jne 0x421c
movq -0x150(%rbp), %rax
movl 0xb4(%rax), %ecx
cmpl 0xb8(%rax), %ecx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
movl %ecx, 0xbc(%rax)
jmp 0x421c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x420b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x31e0
leaq -0x119(%rbp), %rdi
callq 0x3300
jmp 0x4505
jmp 0x421e
movq -0x150(%rbp), %rdi
addq $0x8, %rdi
callq 0x6230
movq -0x150(%rbp), %rdi
addl $0x1, %eax
movl %eax, -0x210(%rbp)
addq $0x8, %rdi
callq 0x6250
movq -0x150(%rbp), %rdi
movl %eax, %ecx
movl -0x210(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x120(%rbp)
movl -0x120(%rbp), %eax
movl %eax, -0x20c(%rbp)
movq 0x100(%rdi), %rax
movq %rax, -0x208(%rbp)
addq $0x8, %rdi
callq 0x6230
movl -0x20c(%rbp), %esi
movq -0x208(%rbp), %rcx
movl $0x20, %edi
cltd
idivl %edi
movq -0x150(%rbp), %rax
movslq %edx, %rdx
movl %esi, (%rcx,%rdx,4)
cmpl $0x1, 0xbc(%rax)
jne 0x435b
movq -0x150(%rbp), %rdi
movq 0xf8(%rdi), %rax
movq %rax, -0x220(%rbp)
addq $0x8, %rdi
callq 0x6230
movq -0x150(%rbp), %rdi
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x220(%rbp), %rax
movslq %edx, %rcx
movl (%rax,%rcx,4), %edx
addl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movq 0xf8(%rdi), %rax
movq %rax, -0x218(%rbp)
addq $0x8, %rdi
callq 0x6230
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x218(%rbp), %rax
movslq %edx, %rcx
cmpl $0x4, (%rax,%rcx,4)
jne 0x4356
movq -0x150(%rbp), %rdi
movq 0xf8(%rdi), %rax
movq %rax, -0x228(%rbp)
addq $0x8, %rdi
callq 0x6230
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x228(%rbp), %rax
movslq %edx, %rcx
movl $0x3, (%rax,%rcx,4)
jmp 0x4403
movq -0x150(%rbp), %rdi
movq 0xf8(%rdi), %rax
movq %rax, -0x238(%rbp)
addq $0x8, %rdi
callq 0x6230
movq -0x150(%rbp), %rdi
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x238(%rbp), %rax
movslq %edx, %rcx
movl (%rax,%rcx,4), %edx
subl $0x1, %edx
movl %edx, (%rax,%rcx,4)
movq 0xf8(%rdi), %rax
movq %rax, -0x230(%rbp)
addq $0x8, %rdi
callq 0x6230
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x230(%rbp), %rax
movslq %edx, %rcx
cmpl $-0x1, (%rax,%rcx,4)
jne 0x4401
movq -0x150(%rbp), %rdi
movq 0xf8(%rdi), %rax
movq %rax, -0x240(%rbp)
addq $0x8, %rdi
callq 0x6230
movl $0x20, %ecx
cltd
idivl %ecx
movq -0x240(%rbp), %rax
movslq %edx, %rcx
movl $0x0, (%rax,%rcx,4)
jmp 0x4403
movq -0x150(%rbp), %rcx
movl 0xbc(%rcx), %eax
cmpl 0x78(%rcx), %eax
jne 0x443f
movq -0x150(%rbp), %rax
cmpl $0x1, 0xbc(%rax)
jne 0x44f4
movq -0x150(%rbp), %rcx
movl -0x120(%rbp), %eax
cmpl 0x7c(%rcx), %eax
je 0x44f4
movq -0x150(%rbp), %rax
cmpl $0x0, 0xbc(%rax)
jne 0x4468
movq -0x150(%rbp), %rdi
addq $0x8, %rdi
callq 0x6230
addl $0x1, %eax
movl %eax, -0x120(%rbp)
movq -0x150(%rbp), %rdi
movq 0xe0(%rdi), %rax
movq %rax, -0x258(%rbp)
addq $0x8, %rdi
callq 0x6270
movq -0x258(%rbp), %rdi
movl %eax, %esi
movq (%rdi), %rax
callq *0x10(%rax)
movq -0x150(%rbp), %rdi
movq 0xe8(%rdi), %rax
movq %rax, -0x250(%rbp)
addq $0x8, %rdi
callq 0x6270
movq -0x250(%rbp), %rdi
movl %eax, %esi
movq (%rdi), %rax
callq *0x10(%rax)
movq -0x150(%rbp), %rdi
movq 0xf0(%rdi), %rax
movq %rax, -0x248(%rbp)
addq $0x8, %rdi
callq 0x6270
movq -0x248(%rbp), %rdi
movl %eax, %esi
movl -0x120(%rbp), %edx
callq 0xddf0
jmp 0x44f6
jmp 0x44f8
jmp 0x44fa
jmp 0x44fc
addq $0x260, %rsp            # imm = 0x260
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x3480
nop