// File: /workspace/github_c_makefile_star2_O1/jtuu[P]quesler/src/compiler.c
// Function: binary
static void binary(bool can_assign) {
    UNUSED(can_assign);

    int ret;
    uint8_t reg1, reg2;

    if ((ret = alloc_register()) < 0) {
        error_alloc_register();
        return;
    }

    reg1 = (uint8_t) ret;

    if ((ret = alloc_register()) < 0) {
        free_register(reg1);
        error_alloc_register();
        return;
    }

    reg2 = (uint8_t) ret;

#define BINARY_OP_I(opcode) \
    do { \
        emit_stack_pop(reg2); \
        emit_stack_pop(reg1); \
 \
        emit_opcode(opcode); \
        emit_register(reg1); \
        emit_register(reg2); \
 \
        emit_stack_push(reg1); \
 \
        free_register(reg1); \
        free_register(reg2); \
    } while (false)

#define COMPARISON_OP(opcode) \
    do { \
        size_t label_true = take_label(); \
        size_t label_continue = take_label(); \
 \
        emit_stack_pop(reg2); \
        emit_stack_pop(reg1); \
 \
        emit_conditional_jump_rr(opcode, reg1, reg2, label_true); \
 \
        emit_stack_push_value(CONSTANT_FALSE); \
        emit_jump(label_continue); \
 \
        set_label_here(label_true); \
        emit_stack_push_value(CONSTANT_TRUE); \
 \
        set_label_here(label_continue); \
    } while (false)

    TokenType operator_type = parser.previous.type;

    ParseRule* rule = get_rule(operator_type);
    parse_precedence((Precedence) (rule->precedence + 1));

    switch (operator_type) {
        case TOKEN_PLUS: 
            BINARY_OP_I(OP_ADD);
            break;
        case TOKEN_MINUS:
            BINARY_OP_I(OP_SUB);
            break;
        case TOKEN_STAR:
            BINARY_OP_I(OP_MUL);
            break;
        case TOKEN_SLASH:
            BINARY_OP_I(OP_DIV);
            break;
        case TOKEN_EQUAL_EQUAL:
            COMPARISON_OP(OP_JMP_EQ);
            break;
        case TOKEN_BANG_EQUAL:
            COMPARISON_OP(OP_JMP_NEQ);
            break;
        case TOKEN_GREATER:
            COMPARISON_OP(OP_JMP_GT);
            break;
        case TOKEN_LESS:
            COMPARISON_OP(OP_JMP_LT);
            break;
        case TOKEN_GREATER_EQUAL:
            COMPARISON_OP(OP_JMP_GTE);
            break;
        case TOKEN_LESS_EQUAL:
            COMPARISON_OP(OP_JMP_LTE);
            break;
        default:
            error("Unknown token");
            break;
    }

    free_register(reg1);
    free_register(reg2);

#undef BINARY_OP_I
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
xorl %r13d, %r13d
leaq 0x12645(%rip), %r12     # 0x175a8
cmpb $0x1, 0x7a(%r13,%r12)
je 0x4f7f
incq %r13
cmpq $0x100, %r13            # imm = 0x100
jne 0x4f63
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
jmp 0x4f8b
movb $0x0, 0x7a(%r13,%r12)
incl 0x1260d(%rip)           # 0x17598
testl %r13d, %r13d
js 0x5086
xorl %ebp, %ebp
cmpb $0x1, 0x7a(%rbp,%r12)
je 0x4fb1
incq %rbp
cmpq $0x100, %rbp            # imm = 0x100
jne 0x4f96
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x4fbd
movb $0x0, 0x7a(%rbp,%r12)
incl 0x125db(%rip)           # 0x17598
testl %ebp, %ebp
js 0x505b
movl 0x12605(%rip), %ebx     # 0x175d0
leaq (%rbx,%rbx,2), %rax
leaq 0x1210a(%rip), %rcx     # 0x170e0
movl 0x10(%rcx,%rax,8), %edi
incl %edi
callq 0x606f
leal -0x5(%rbx), %eax
cmpl $0xf, %eax
ja 0x52da
leaq 0x5058(%rip), %rcx      # 0xa04c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl %bpl, %edi
callq 0x61cc
movzbl %r13b, %ebx
movl %ebx, %edi
callq 0x61cc
leaq 0xf(%rsp), %rdx
movb $0x1a, (%rdx)
movq 0x12580(%rip), %rdi     # 0x175a0
movq 0x125c1(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x10(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x12560(%rip), %rdi     # 0x175a0
movq 0x125a1(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x11(%rsp), %rdx
jmp 0x534b
movzbl %r13b, %ebx
cmpb $0x1, 0x7a(%rbx,%r12)
jne 0x507a
leaq 0x12562(%rip), %rdi     # 0x175d0
leaq 0x527f(%rip), %rsi      # 0xa2f4
callq 0x6108
movb $0x1, 0x7a(%rbx,%r12)
decl 0x12512(%rip)           # 0x17598
leaq 0x12543(%rip), %rdi     # 0x175d0
leaq 0x5244(%rip), %rsi      # 0xa2d8
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6108
movzbl %bpl, %edi
callq 0x61cc
movzbl %r13b, %ebx
movl %ebx, %edi
callq 0x61cc
leaq 0x15(%rsp), %rdx
movb $0x1e, (%rdx)
movq 0x124d6(%rip), %rdi     # 0x175a0
movq 0x12517(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x16(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x124b6(%rip), %rdi     # 0x175a0
movq 0x124f7(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x17(%rsp), %rdx
jmp 0x534b
movq 0x1261c(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12612(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x5132
leaq 0x124aa(%rip), %rdi     # 0x175d0
leaq 0x51ea(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x125ef(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x125e5(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x515f
leaq 0x1247d(%rip), %rdi     # 0x175d0
leaq 0x51bd(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x2c, %edi
jmp 0x5537
movzbl %bpl, %edi
callq 0x61cc
movzbl %r13b, %ebx
movl %ebx, %edi
callq 0x61cc
leaq 0xc(%rsp), %rdx
movb $0x18, (%rdx)
movq 0x123fb(%rip), %rdi     # 0x175a0
movq 0x1243c(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0xd(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x123db(%rip), %rdi     # 0x175a0
movq 0x1241c(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0xe(%rsp), %rdx
jmp 0x534b
movq 0x12541(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12537(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x520d
leaq 0x123cf(%rip), %rdi     # 0x175d0
leaq 0x510f(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x12514(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x1250a(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x523a
leaq 0x123a2(%rip), %rdi     # 0x175d0
leaq 0x50e2(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x32, %edi
jmp 0x5537
movq 0x124c4(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x124ba(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x528a
leaq 0x12352(%rip), %rdi     # 0x175d0
leaq 0x5092(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x12497(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x1248d(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x52b7
leaq 0x12325(%rip), %rdi     # 0x175d0
leaq 0x5065(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x3a, %edi
jmp 0x5537
leaq 0x122ef(%rip), %rdi     # 0x175d0
leaq 0x5021(%rip), %rsi      # 0xa309
callq 0x6108
jmp 0x5583
movzbl %bpl, %edi
callq 0x61cc
movzbl %r13b, %ebx
movl %ebx, %edi
callq 0x61cc
leaq 0x12(%rsp), %rdx
movb $0x1c, (%rdx)
movq 0x1228b(%rip), %rdi     # 0x175a0
movq 0x122cc(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x13(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x1226b(%rip), %rdi     # 0x175a0
movq 0x122ac(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
leaq 0x14(%rsp), %rdx
movb %bpl, (%rdx)
movq 0x1224b(%rip), %rdi     # 0x175a0
movq 0x1228c(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4574
movl %ebx, %edi
callq 0x6180
movzbl %r13b, %ebx
cmpb $0x1, 0x7a(%rbx,%r12)
jne 0x538c
leaq 0x12250(%rip), %rdi     # 0x175d0
leaq 0x4f6d(%rip), %rsi      # 0xa2f4
callq 0x6108
decl 0x12206(%rip)           # 0x17598
movb $0x1, 0x7a(%rbx,%r12)
movzbl %bpl, %ebx
cmpb $0x1, 0x7a(%rbx,%r12)
jne 0x53b7
leaq 0x12225(%rip), %rdi     # 0x175d0
leaq 0x4f42(%rip), %rsi      # 0xa2f4
callq 0x6108
movb $0x1, 0x7a(%rbx,%r12)
decl 0x121d5(%rip)           # 0x17598
jmp 0x5583
movq 0x12359(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x1234f(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x53f5
leaq 0x121e7(%rip), %rdi     # 0x175d0
leaq 0x4f27(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x1232c(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x12322(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x5422
leaq 0x121ba(%rip), %rdi     # 0x175d0
leaq 0x4efa(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x2e, %edi
jmp 0x5537
movq 0x122dc(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x122d2(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x5472
leaq 0x1216a(%rip), %rdi     # 0x175d0
leaq 0x4eaa(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x122af(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x122a5(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x549f
leaq 0x1213d(%rip), %rdi     # 0x175d0
leaq 0x4e7d(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x3e, %edi
jmp 0x5537
movq 0x12262(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12258(%rip)     # 0x17728
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x54ec
leaq 0x120f0(%rip), %rdi     # 0x175d0
leaq 0x4e30(%rip), %rsi      # 0xa317
callq 0x6108
movq 0x12235(%rip), %r14     # 0x17728
incq %r14
movq %r14, 0x1222b(%rip)     # 0x17728
cmpq $0x10000, %r14          # imm = 0x10000
jb 0x5519
leaq 0x120c3(%rip), %rdi     # 0x175d0
leaq 0x4e03(%rip), %rsi      # 0xa317
callq 0x6108
movzbl %bpl, %edi
movl %edi, 0x8(%rsp)
callq 0x61cc
movzbl %r13b, %r15d
movl %r15d, %edi
callq 0x61cc
movl $0x36, %edi
movl %r15d, %esi
movl 0x8(%rsp), %edx
movq %rbx, %rcx
callq 0x6363
xorl %edi, %edi
callq 0x6266
movq %r14, %rdi
callq 0x63e1
movq 0x12044(%rip), %rdi     # 0x175a0
movswl (%rdi), %edx
movq %rbx, %rsi
callq 0x469b
movl $0x1, %edi
callq 0x6266
movq 0x12028(%rip), %rdi     # 0x175a0
movswl (%rdi), %edx
movq %r14, %rsi
callq 0x469b
movzbl %r13b, %ebx
cmpb $0x1, 0x7a(%rbx,%r12)
jne 0x55a2
leaq 0x1203a(%rip), %rdi     # 0x175d0
leaq 0x4d57(%rip), %rsi      # 0xa2f4
callq 0x6108
decl 0x11ff0(%rip)           # 0x17598
movb $0x1, 0x7a(%rbx,%r12)
movzbl %bpl, %ebx
cmpb $0x1, 0x7a(%rbx,%r12)
jne 0x55cd
leaq 0x1200f(%rip), %rdi     # 0x175d0
leaq 0x4d2c(%rip), %rsi      # 0xa2f4
callq 0x6108
movb $0x1, 0x7a(%rbx,%r12)
decl 0x11fbf(%rip)           # 0x17598
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq