// File: vssense[P]Compiler/src/back-end/compiling.cpp
// Function: WriteAsmCondition(Node*, Compiler*)
void WriteAsmCondition(Node* node, Compiler* compiler)
{
    ASSERT_COMPILER;

    WriteAsmExpression(node->left, compiler);

    size_t true_label = compiler->label++;
    size_t false_label = compiler->label++;
    size_t continue_label = compiler->label++;

    WritePopR64(compiler, RAX);
    WriteTest  (compiler, RAX, RAX);

    size_t true_jump_offset  = WriteJumpOp(compiler, NOT_EQUAL_OP, true_label);
    size_t false_jump_offset = WriteJump  (compiler, false_label);
    size_t true_label_offset = WriteLabel (compiler, true_label);

    WriteAsmCompound(node->right->left->right, compiler);

    size_t continue_jump_offset = WriteJump(compiler, continue_label);
    size_t false_label_offset   = WriteLabel(compiler, false_label);

    if (node->right->right != nullptr)
    {
        WriteAsmCompound(node->right->right->right, compiler);
    }

    size_t continue_label_offset = WriteLabel(compiler, continue_label);

    SetInt(&compiler->writer, true_label_offset - true_jump_offset - sizeof(int), true_jump_offset);
    SetInt(&compiler->writer, false_label_offset - false_jump_offset - sizeof(int), false_jump_offset);
    SetInt(&compiler->writer, continue_label_offset - continue_jump_offset - sizeof(int), continue_jump_offset);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x33a0
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x18(%rcx)
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x18(%rcx)
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x18(%rcx)
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0x5020
movq -0x10(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x5320
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rdx
movl $0x5, %esi
xorl %eax, %eax
movl %eax, %ecx
callq 0x5400
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x54e0
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x5590
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x3090
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x54e0
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x5590
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
cmpq $0x0, 0x20(%rax)
je 0x3535
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rax
movq 0x20(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x3090
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x5590
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x40(%rbp), %rax
subq -0x30(%rbp), %rax
subq $0x4, %rax
movl %eax, %esi
movq -0x30(%rbp), %rdx
callq 0x5f90
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x50(%rbp), %rax
subq -0x38(%rbp), %rax
subq $0x4, %rax
movl %eax, %esi
movq -0x38(%rbp), %rdx
callq 0x5f90
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x58(%rbp), %rax
subq -0x48(%rbp), %rax
subq $0x4, %rax
movl %eax, %esi
movq -0x48(%rbp), %rdx
callq 0x5f90
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)