// File: /workspace/github_c_makefile_star2_O0/gregtour[P]minimal-compiler/intermediate.c
// Function: GenerateExprIRCode
int GenerateExprIRCode(EXPR* expression, FUNC_SEGMENT* segment)
{
    switch (expression->production)
    {
    case PROD_CONDITION_AND:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("AND");
        break;
    }
    case PROD_CONDITION_OR:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("OR");
        break;
    }
    case PROD_LOGIC_NOT:
    {
        GenerateExprIRCode(expression->children[1], segment);
        PUSH_INST("NOT");
        break;
    }
    case PROD_COMPARISON_EQUAL_TO:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-EQUAL");
        break;
    }
    case PROD_COMPARISON_UNEQUAL_TO:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-UNEQUAL");
        break;
    }
    case PROD_COMPARISON_LESS:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-LESS");
        break;
    }
    case PROD_COMPARISON_GREATER:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-GREATER");
        break;
    }
    case PROD_COMPARISON_L_EQUAL:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-LESS-EQUAL");
        break;
    }
    case PROD_COMPARISON_G_EQUAL:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("CMP-GREATER-EQUAL");
        break;
    }
    case PROD_ARITHMETIC_ADD:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("ADD");
        break;
    }
    case PROD_ARITHMETIC_SUBTRACT:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("SUB");
        break;
    }
    case PROD_TERM_MULTIPLY:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("MULT");
        break;
    }
    case PROD_TERM_DIVIDE:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("DIV");
        break;
    }
    case PROD_TERM_MODULUS:
    {
        GenerateExprIRCode(expression->children[0], segment);
        GenerateExprIRCode(expression->children[2], segment);
        PUSH_INST("MOD");
        break;
    }
    case PROD_FACTOR_MINUS:
    {
        GenerateExprIRCode(expression->children[1], segment);
        PUSH_INST("MINUS");
        break;
    }
    case PROD_FACTOR_NOT:
    {
        GenerateExprIRCode(expression->children[1], segment);
        PUSH_INST("NOT");
        break;
    }
    case PROD_FINAL_FUNCTION_CALL:
    {
        //for each argument
        // GenerateExprIRCode();
        //  
        PUSH_INST("CALL funcname");
        break;
    }
    case PROD_FINAL_BOOLEAN:
    {
        // one of the following
        PUSH_INST("PUSH TRUE");
        PUSH_INST("PUSH FALSE");
        break;
    }
    case PROD_FINAL_IDENTIFIER:
    case PROD_FINAL_INTEGER:
    default:
        // one of the following
        PUSH_INST("PUSH <variable>");
        PUSH_INST("PUSH <final>");
        break;
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movl 0x4(%rax), %eax
addl $-0x24, %eax
movl %eax, %ecx
movq %rcx, -0x18(%rbp)
subl $0x1a, %eax
ja 0x5a7b
movq -0x18(%rbp), %rax
leaq 0x5c74(%rip), %rcx      # 0xb448
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rdi
movq -0x10(%rbp), %rsi
callq 0x57a0
jmp 0x5a7d
jmp 0x5a7d
jmp 0x5a7d
jmp 0x5a7b
jmp 0x5a7d
xorl %eax, %eax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nop