// File: /workspace/github_cpp_makefile_star2_O2/Ziang95[P]Tomasulo_simulator/FU.cpp
// Function: intAdder::FU_automat()
void intAdder::FU_automat()
{
    next_vdd = 0;
    while (true)
    {
A:      at_rising_edge(next_vdd);
        if (squash_p.flag)
        {
            squash_p.flag = false;
            at_falling_edge(next_vdd);
            continue;
        }
        auto newTask = queue.deQ();
        if (newTask)
        {
            task = *newTask;
            ROBEntry *R = CPU_ROB->get_entry(task.dest);
            R->output.exe = sys_clk.get_prog_cyc();
            for (int i = 0; ;i++)
            {
                if (squash_p.flag)
                {
                    squash_p.flag = false;
                    if (is_prev_index(squash_p.ROB_i, task.dest, squash_p.R_f, squash_p.R_r))
                        break;
                }
                msg_log("Calculating INT "+to_string(task.oprnd1->i)+" + "+to_string(task.oprnd2->i) + " dest ROB = " + to_string(task.dest), 3);
                if (i == CPU_cfg->int_add->exe_time - 1)
                {
                    if (task.code == BEQ || task.code == BNE)
                    {
                        *task.busy = false;
                        bool branch = false;
                        int result = task.oprnd1->i - task.oprnd2->i;
                        if (result)
                            branch = task.code == BNE? true:false;
                        else
                            branch = task.code == BEQ? true:false;
                        if (auto tmp = CPU_BTB.getEntry(R->instr_i))
                        {
                            if (branch == tmp->taken)
                            {
                                if (tmp->taken && tmp->target != R->instr_i + 1 + task.offset)
                                {
                                    tmp->target = R->instr_i + 1 +task.offset;
                                    brcUnit.to_target(R->instr_i + 1 + task.offset);
                                    msg_log("Begin Squash", 3);
                                    brcUnit.to_squash(task.dest);   
                                    at_falling_edge(next_vdd);
                                }
                                else
                                {
                                    at_falling_edge(next_vdd);
                                    R->finished = true;
                                }
                            }
                            else
                            {
                                tmp->taken = branch;
                                if (branch)
                                    brcUnit.to_target(tmp->target);
                                else
                                    brcUnit.to_target(R->instr_i + 1);
                                msg_log("Begin Squash", 3);
                                brcUnit.to_squash(task.dest);
                                at_falling_edge(next_vdd);
                            }
                        }
                        else
                        {
                            if (branch)
                            {
                                CPU_BTB.addEntry(R->instr_i, R->instr_i + 1 + task.offset);
                                brcUnit.to_target(R->instr_i + 1 + task.offset);
                                msg_log("Begin Squash", 3);
                                brcUnit.to_squash(task.dest);
                                at_falling_edge(next_vdd);
                            }
                            else
                            {
                                at_falling_edge(next_vdd);
                                R->finished = true;
                            }
                        }
                        goto A;
                    }
                    else
                    {
                        task.res->i = task.oprnd1->i + task.oprnd2->i;
                        msg_log("CDB enqueued, ROB = " + to_string(task.dest), 3);
                        fCDB.enQ(task.res, task.dest);
                    }
                    break;
                }
                at_falling_edge(next_vdd);
                at_rising_edge(next_vdd);
            }
        }
        at_falling_edge(next_vdd);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdi, %r14
andl $0x0, 0x3888(%rdi)
leaq 0x3888(%rdi), %r15
leaq 0x8(%rdi), %rax
movq %rax, -0x70(%rbp)
leaq 0x3838(%rdi), %rax
movq %rax, -0x40(%rbp)
leaq -0x190(%rbp), %rbx
movq %r15, -0x48(%rbp)
movq %r15, %rdi
callq 0x83e0
cmpb $0x1, 0x38a4(%r14)
jne 0x41c4
movb $0x0, 0x38a4(%r14)
jmp 0x45ec
movq -0x70(%rbp), %rdi
callq 0x3f84
testq %rax, %rax
je 0x45ec
movq 0x30(%rax), %rcx
movq -0x40(%rbp), %rdx
movq %rcx, 0x30(%rdx)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movups %xmm2, 0x20(%rdx)
movups %xmm1, 0x10(%rdx)
movups %xmm0, (%rdx)
leaq 0x12171(%rip), %rax     # 0x16370
movq (%rax), %rdi
movl 0x383c(%r14), %esi
callq 0x6c7e
movq %rax, %r12
leaq 0x12a90(%rip), %rdi     # 0x16ca8
callq 0x7e24
movq %r12, -0x30(%rbp)
movl %eax, 0x54(%r12)
movl $0x0, -0x34(%rbp)
cmpb $0x1, 0x38a4(%r14)
jne 0x4268
movb $0x0, 0x38a4(%r14)
movl 0x38a0(%r14), %edi
movl 0x383c(%r14), %esi
movl 0x3898(%r14), %edx
movl 0x389c(%r14), %ecx
callq 0xc3de
testb %al, %al
jne 0x45ec
movq %r14, %r13
movq 0x3848(%r14), %rax
movl (%rax), %esi
leaq -0xf0(%rbp), %r12
movq %r12, %rdi
callq 0x5ab8
leaq -0x110(%rbp), %r14
movq %r14, %rdi
leaq 0xadaf(%rip), %rsi      # 0xf043
movq %r12, %rdx
callq 0x5a8a
leaq -0x90(%rbp), %rdi
movq %r14, %rsi
leaq 0xada7(%rip), %rdx      # 0xf054
callq 0x5bc8
movq 0x3850(%r13), %rax
movl (%rax), %esi
movq %rbx, %r14
movq %rbx, %rdi
callq 0x5ab8
leaq -0x1b0(%rbp), %r15
movq %r15, %rdi
leaq -0x90(%rbp), %rsi
movq %r14, %rdx
callq 0x5b57
leaq -0x68(%rbp), %rdi
movq %r15, %rsi
leaq 0xb771(%rip), %rdx      # 0xfa5e
callq 0x5bc8
movq %r15, %r14
movl 0x383c(%r13), %esi
leaq -0xd0(%rbp), %r15
movq %r15, %rdi
callq 0x5ab8
leaq -0x1d0(%rbp), %r12
movq %r12, %rdi
leaq -0x68(%rbp), %rsi
movq %r15, %rdx
callq 0x5b57
movq %r12, %rdi
pushq $0x3
popq %rsi
callq 0x8343
movq %r12, %rdi
callq 0x3140
leaq -0xd0(%rbp), %rdi
callq 0x3140
leaq -0x68(%rbp), %rdi
callq 0x3140
movq %r14, %rdi
callq 0x3140
movq %rbx, %rdi
callq 0x3140
leaq -0x90(%rbp), %rdi
callq 0x3140
leaq -0x110(%rbp), %rdi
callq 0x3140
leaq -0xf0(%rbp), %rdi
callq 0x3140
leaq 0x11fdc(%rip), %rax     # 0x16360
movq (%rax), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
decl %eax
movl -0x34(%rbp), %r14d
cmpl %eax, %r14d
je 0x43bc
movq -0x48(%rbp), %r15
movq %r15, %rdi
callq 0x8437
movq %r15, %rdi
callq 0x83e0
incl %r14d
movl %r14d, -0x34(%rbp)
movq %r13, %r14
jmp 0x422d
movq -0x40(%rbp), %rax
movl (%rax), %eax
andl $-0x2, %eax
cmpl $0x8, %eax
movq %r13, %r14
movq -0x48(%rbp), %r15
jne 0x448b
movq 0x3868(%r14), %rax
movb $0x0, (%rax)
movq 0x3848(%r14), %rax
movl (%rax), %eax
movq 0x3850(%r14), %rcx
xorl %r13d, %r13d
cmpl (%rcx), %eax
sete %r13b
movl 0x3838(%r14), %r12d
orl $0x8, %r13d
movq -0x30(%rbp), %rax
movl 0x64(%rax), %esi
leaq 0x11f67(%rip), %rdi     # 0x16378
callq 0x770a
testq %rax, %rax
je 0x450d
cmpl %r13d, %r12d
sete %cl
movb 0x5(%rax), %dl
cmpb %cl, %dl
jne 0x458b
testb %dl, %dl
je 0x4577
movq -0x30(%rbp), %rcx
movl 0x64(%rcx), %ecx
movl 0x3860(%r14), %edx
leal (%rcx,%rdx), %esi
incl %esi
cmpl %esi, (%rax)
je 0x4577
movl %esi, (%rax)
leaq 0x11f3c(%rip), %rdi     # 0x16398
callq 0x773e
leaq -0x170(%rbp), %r12
movq %r12, %rdi
leaq 0xabe6(%rip), %rsi      # 0xf058
leaq -0x68(%rbp), %rdx
callq 0x3100
movq %r12, %rdi
pushq $0x3
popq %rsi
callq 0x8343
jmp 0x45d1
movq 0x3840(%r14), %rax
movq 0x3848(%r14), %rcx
movq 0x3850(%r14), %rdx
movl (%rdx), %edx
addl (%rcx), %edx
movl %edx, (%rax)
movl 0x383c(%r14), %esi
leaq -0x68(%rbp), %r12
movq %r12, %rdi
callq 0x5ab8
leaq -0x130(%rbp), %r13
movq %r13, %rdi
leaq 0xab9b(%rip), %rsi      # 0xf065
movq %r12, %rdx
callq 0x5a8a
movq %r13, %rdi
pushq $0x3
popq %rsi
callq 0x8343
movq %r13, %rdi
callq 0x3140
leaq -0x68(%rbp), %rdi
callq 0x3140
movq 0x3840(%r14), %rsi
movl 0x383c(%r14), %edx
leaq 0x11f1d(%rip), %rdi     # 0x16420
callq 0x3a0e
jmp 0x45ec
cmpl %r13d, %r12d
jne 0x4577
movq -0x30(%rbp), %r12
movl 0x64(%r12), %esi
movl 0x3860(%r14), %eax
leal (%rsi,%rax), %edx
incl %edx
leaq 0x11e4a(%rip), %rdi     # 0x16378
callq 0x76ea
movl 0x64(%r12), %eax
movl 0x3860(%r14), %ecx
leal (%rax,%rcx), %esi
incl %esi
leaq 0x11e4d(%rip), %rdi     # 0x16398
callq 0x773e
leaq -0x150(%rbp), %r12
movq %r12, %rdi
leaq 0xaaf7(%rip), %rsi      # 0xf058
leaq -0x68(%rbp), %rdx
callq 0x3100
movq %r12, %rdi
pushq $0x3
popq %rsi
callq 0x8343
jmp 0x45d1
movq %r15, %rdi
callq 0x8437
movq -0x30(%rbp), %rax
movb $0x1, (%rax)
jmp 0x41a5
movb %cl, 0x5(%rax)
cmpl %r13d, %r12d
jne 0x4597
movl (%rax), %esi
jmp 0x45a0
movq -0x30(%rbp), %rax
movl 0x64(%rax), %esi
incl %esi
leaq -0xb0(%rbp), %r12
leaq 0x11dea(%rip), %rdi     # 0x16398
callq 0x773e
movq %r12, %rdi
leaq 0xaa9b(%rip), %rsi      # 0xf058
leaq -0x68(%rbp), %rdx
callq 0x3100
movq %r12, %rdi
pushq $0x3
popq %rsi
callq 0x8343
movq %r12, %rdi
callq 0x3140
movl 0x383c(%r14), %esi
leaq 0x11db1(%rip), %rdi     # 0x16398
callq 0x7736
movq %r15, %rdi
callq 0x8437
jmp 0x41a5
movq %rax, %rbx
leaq -0x170(%rbp), %rdi
jmp 0x46ca
jmp 0x462a
movq %rax, %rbx
leaq -0x150(%rbp), %rdi
jmp 0x46ca
jmp 0x462a
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
jmp 0x46ca
movq %rax, %rbx
jmp 0x46cf
movq %rax, %rbx
leaq -0x130(%rbp), %rdi
callq 0x3140
jmp 0x4646
movq %rax, %rbx
leaq -0x68(%rbp), %rdi
jmp 0x46ca
movq %rax, %rbx
jmp 0x467f
movq %rax, %rbx
jmp 0x4676
movq %rax, %rbx
jmp 0x466a
movq %rax, %rbx
leaq -0x1d0(%rbp), %rdi
callq 0x3140
leaq -0xd0(%rbp), %rdi
callq 0x3140
leaq -0x68(%rbp), %rdi
callq 0x3140
leaq -0x1b0(%rbp), %rdi
callq 0x3140
jmp 0x469f
movq %rax, %rbx
jmp 0x46c3
movq %rax, %rbx
jmp 0x46b7
movq %rax, %rbx
jmp 0x46ab
movq %rax, %rbx
leaq -0x190(%rbp), %rdi
callq 0x3140
leaq -0x90(%rbp), %rdi
callq 0x3140
leaq -0x110(%rbp), %rdi
callq 0x3140
leaq -0xf0(%rbp), %rdi
callq 0x3140
movq %rbx, %rdi
callq 0x3440
nop