// File: /workspace/github_c_makefile_star2_O3/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 $0x0, 0x7a(%r13,%r12)
jne 0x4f79
incq %r13
cmpq $0x100, %r13            # imm = 0x100
jne 0x4f63
jmp 0x4fd4
movb $0x0, 0x7a(%r13,%r12)
movl 0x12613(%rip), %eax     # 0x17598
leal 0x1(%rax), %ecx
movl %ecx, 0x1260a(%rip)     # 0x17598
xorl %r14d, %r14d
cmpb $0x0, 0x7a(%r14,%r12)
jne 0x4ff5
incq %r14
cmpq $0x100, %r14            # imm = 0x100
jne 0x4f91
cmpb $0x1, 0x7a(%r13,%r12)
jne 0x4fc8
leaq 0x1261c(%rip), %rdi     # 0x175d0
leaq 0x535d(%rip), %rsi      # 0xa318
callq 0x608e
movl 0x125d2(%rip), %eax     # 0x17598
decl %eax
movb $0x1, 0x7a(%r13,%r12)
movl %eax, 0x125c4(%rip)     # 0x17598
leaq 0x125f5(%rip), %rdi     # 0x175d0
leaq 0x531a(%rip), %rsi      # 0xa2fc
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x608e
movb $0x0, 0x7a(%r14,%r12)
addl $0x2, %eax
movl %eax, 0x12594(%rip)     # 0x17598
movl 0x125c6(%rip), %ebx     # 0x175d0
leaq (%rbx,%rbx,2), %rax
leaq 0x120cb(%rip), %rcx     # 0x170e0
movl 0x10(%rcx,%rax,8), %edi
incl %edi
callq 0x5ff5
leal -0x5(%rbx), %eax
cmpl $0xf, %eax
ja 0x52fa
leaq 0x5019(%rip), %rcx      # 0xa04c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0xff, %ebx
movl %r14d, %edi
andl %ebx, %edi
callq 0x6150
andl %r13d, %ebx
movl %ebx, %edi
callq 0x6150
leaq 0xf(%rsp), %rdx
movb $0x1a, (%rdx)
movq 0x1253c(%rip), %rdi     # 0x175a0
movq 0x1257d(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x10(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x1251c(%rip), %rdi     # 0x175a0
movq 0x1255d(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x11(%rsp), %rdx
jmp 0x5370
movl $0xff, %ebx
movl %r14d, %edi
andl %ebx, %edi
callq 0x6150
andl %r13d, %ebx
movl %ebx, %edi
callq 0x6150
leaq 0x15(%rsp), %rdx
movb $0x1e, (%rdx)
movq 0x124d9(%rip), %rdi     # 0x175a0
movq 0x1251a(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x16(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x124b9(%rip), %rdi     # 0x175a0
movq 0x124fa(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x17(%rsp), %rdx
jmp 0x5370
movq 0x1261f(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12615(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x5139
leaq 0x124aa(%rip), %rdi     # 0x175d0
leaq 0x520e(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x125ef(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x125e5(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x5162
leaq 0x1247a(%rip), %rdi     # 0x175d0
leaq 0x51de(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x2c, %edi
jmp 0x5585
movl $0xff, %ebx
movl %r14d, %edi
andl %ebx, %edi
callq 0x6150
andl %r13d, %ebx
movl %ebx, %edi
callq 0x6150
leaq 0xc(%rsp), %rdx
movb $0x18, (%rdx)
movq 0x123ef(%rip), %rdi     # 0x175a0
movq 0x12430(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0xd(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x123cf(%rip), %rdi     # 0x175a0
movq 0x12410(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0xe(%rsp), %rdx
jmp 0x5370
movq 0x12535(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x1252b(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x5223
leaq 0x123c0(%rip), %rdi     # 0x175d0
leaq 0x5124(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x12505(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x124fb(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x524c
leaq 0x12390(%rip), %rdi     # 0x175d0
leaq 0x50f4(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x32, %edi
jmp 0x5585
movq 0x124ae(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x124a4(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x52aa
leaq 0x12339(%rip), %rdi     # 0x175d0
leaq 0x509d(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x1247e(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x12474(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x52d3
leaq 0x12309(%rip), %rdi     # 0x175d0
leaq 0x506d(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x3a, %edi
jmp 0x5585
leaq 0x122cf(%rip), %rdi     # 0x175d0
leaq 0x5025(%rip), %rsi      # 0xa32d
callq 0x608e
jmp 0x55d3
movl $0xff, %ebx
movl %r14d, %edi
andl %ebx, %edi
callq 0x6150
andl %r13d, %ebx
movl %ebx, %edi
callq 0x6150
leaq 0x12(%rsp), %rdx
movb $0x1c, (%rdx)
movq 0x12266(%rip), %rdi     # 0x175a0
movq 0x122a7(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x13(%rsp), %rdx
movb %r13b, (%rdx)
movq 0x12246(%rip), %rdi     # 0x175a0
movq 0x12287(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
leaq 0x14(%rsp), %rdx
movb %r14b, (%rdx)
movq 0x12226(%rip), %rdi     # 0x175a0
movq 0x12267(%rip), %rcx     # 0x175e8
movl $0x1, %esi
callq 0x4564
movl %ebx, %edi
callq 0x6104
cmpb $0x1, 0x7a(%r13,%r12)
jne 0x53ad
leaq 0x1222f(%rip), %rdi     # 0x175d0
leaq 0x4f70(%rip), %rsi      # 0xa318
callq 0x608e
movb $0x1, 0x7a(%r13,%r12)
movl 0x121df(%rip), %eax     # 0x17598
decl %eax
movl %eax, 0x121d7(%rip)     # 0x17598
cmpb $0x1, 0x7a(%r14,%r12)
jne 0x53e2
leaq 0x12200(%rip), %rdi     # 0x175d0
leaq 0x4f41(%rip), %rsi      # 0xa318
callq 0x608e
movl 0x121b6(%rip), %eax     # 0x17598
movb $0x1, 0x7a(%r14,%r12)
decl %eax
movl %eax, 0x121a8(%rip)     # 0x17598
jmp 0x55d3
movq 0x1232c(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12322(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x542c
leaq 0x121b7(%rip), %rdi     # 0x175d0
leaq 0x4f1b(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x122fc(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x122f2(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x5455
leaq 0x12187(%rip), %rdi     # 0x175d0
leaq 0x4eeb(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x2e, %edi
jmp 0x5585
movq 0x122a5(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x1229b(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x54b3
leaq 0x12130(%rip), %rdi     # 0x175d0
leaq 0x4e94(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x12275(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x1226b(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x54dc
leaq 0x12100(%rip), %rdi     # 0x175d0
leaq 0x4e64(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x3e, %edi
jmp 0x5585
movq 0x1221e(%rip), %rbx     # 0x17728
incq %rbx
movq %rbx, 0x12214(%rip)     # 0x17728
movq %rbx, %rax
cmpq $0x10000, %rbx          # imm = 0x10000
jb 0x553a
leaq 0x120a9(%rip), %rdi     # 0x175d0
leaq 0x4e0d(%rip), %rsi      # 0xa33b
callq 0x608e
movq 0x121ee(%rip), %rax     # 0x17728
incq %rax
movq %rax, 0x121e4(%rip)     # 0x17728
movq %rax, (%rsp)
cmpq $0x10000, %rax          # imm = 0x10000
jb 0x5563
leaq 0x12079(%rip), %rdi     # 0x175d0
leaq 0x4ddd(%rip), %rsi      # 0xa33b
callq 0x608e
movl $0xff, %ebp
movl %r14d, %r15d
andl %ebp, %r15d
movl %r15d, %edi
callq 0x6150
andl %r13d, %ebp
movl %ebp, %edi
callq 0x6150
movl $0x36, %edi
movl %ebp, %esi
movl %r15d, %edx
movq %rbx, %rcx
callq 0x62d4
xorl %edi, %edi
callq 0x61ea
movq (%rsp), %r15
movq %r15, %rdi
callq 0x6352
movq 0x11ff4(%rip), %rdi     # 0x175a0
movswl (%rdi), %edx
movq %rbx, %rsi
callq 0x4692
movl $0x1, %edi
callq 0x61ea
movq 0x11fd8(%rip), %rdi     # 0x175a0
movswl (%rdi), %edx
movq %r15, %rsi
callq 0x4692
cmpb $0x1, 0x7a(%r13,%r12)
jne 0x55ee
leaq 0x11fee(%rip), %rdi     # 0x175d0
leaq 0x4d2f(%rip), %rsi      # 0xa318
callq 0x608e
movb $0x1, 0x7a(%r13,%r12)
movl 0x11f9e(%rip), %eax     # 0x17598
decl %eax
movl %eax, 0x11f96(%rip)     # 0x17598
cmpb $0x1, 0x7a(%r14,%r12)
jne 0x5623
leaq 0x11fbf(%rip), %rdi     # 0x175d0
leaq 0x4d00(%rip), %rsi      # 0xa318
callq 0x608e
movl 0x11f75(%rip), %eax     # 0x17598
movb $0x1, 0x7a(%r14,%r12)
decl %eax
movl %eax, 0x11f67(%rip)     # 0x17598
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq