// File: /workspace/github_c_makefile_star2_O1/ryvnf[P]czc/parse.c
// Function: parse_binop_expr
static struct ast *parse_binop_expr(struct parse *parse, int prec)
{
    struct ast *lhs_expr = parse_cast_expr(parse);
    if (lhs_expr == NULL)
        goto err0;

    for (;;) {
        enum ast_tag op;
        int rprec, next_prec;

	struct loc *line = get_linenr(parse);
        switch (peek_tok(parse)->type) {
            case ',':
                op = COMMA_EXPR;
                rprec = COMMA_PREC;
                next_prec = rprec + 1;
                break;

            case '=':
                op = ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case ADD_ASGN_TOK:
                op = ADD_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case SUB_ASGN_TOK:
                op = SUB_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case MUL_ASGN_TOK:
                op = MUL_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case DIV_ASGN_TOK:
                op = DIV_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case REM_ASGN_TOK:
                op = REM_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case SHL_ASGN_TOK:
                op = SHL_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case SHR_ASGN_TOK:
                op = SHR_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case OR_ASGN_TOK:
                op = OR_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case XOR_ASGN_TOK:
                op = XOR_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case AND_ASGN_TOK:
                op = AND_ASGN_EXPR;
                next_prec = rprec = ASGN_PREC;
                break;

            case ANDAND_TOK:
                op = LAND_EXPR;
                rprec = TRUTH_AND_PREC;
                next_prec = rprec + 1;
                break;

            case OROR_TOK:
                op = LOR_EXPR;
                rprec = TRUTH_OR_PREC;
                next_prec = rprec + 1;
                break;

            case EQ_TOK:
                op = EQ_EXPR;
                rprec = EQ_PREC;
                next_prec = rprec + 1;
                break;

            case NE_TOK:
                op = NE_EXPR;
                rprec = EQ_PREC;
                next_prec = rprec + 1;
                break;

            case '<':
                op = LT_EXPR;
                rprec = REL_PREC;
                next_prec = rprec + 1;
                break;

            case '>':
                op = GT_EXPR;
                rprec = REL_PREC;
                next_prec = rprec + 1;
                break;

            case LE_TOK:
                op = LE_EXPR;
                rprec = REL_PREC;
                next_prec = rprec + 1;
                break;

            case GE_TOK:
                op = GE_EXPR;
                rprec = REL_PREC;
                next_prec = rprec + 1;
                break;

            case '|':
                op = OR_EXPR;
                rprec = BIT_OR_PREC;
                next_prec = rprec + 1;
                break;

            case '~':
                op = XOR_EXPR;
                rprec = BIT_XOR_PREC;
                next_prec = rprec + 1;
                break;

            case '&':
                op = AND_EXPR;
                rprec = BIT_AND_PREC;
                next_prec = rprec + 1;
                break;

            case SHL_TOK:
                op = SHL_EXPR;
                rprec = SHIFT_PREC;
                next_prec = rprec + 1;
                break;

            case SHR_TOK:
                op = SHR_EXPR;
                rprec = SHIFT_PREC;
                next_prec = rprec + 1;
                break;

            case '+':
                op = ADD_EXPR;
                rprec = ADD_PREC;
                next_prec = rprec + 1;
                break;

            case '-':
                op = SUB_EXPR;
                rprec = ADD_PREC;
                next_prec = rprec + 1;
                break;

            case '*':
                op = MUL_EXPR;
                rprec = MUL_PREC;
                next_prec = rprec + 1;
                break;

            case '/':
                op = DIV_EXPR;
                rprec = MUL_PREC;
                next_prec = rprec + 1;
                break;

            case '%':
                op = REM_EXPR;
                rprec = MUL_PREC;
                next_prec = rprec + 1;
                break;

            case '?':
                op = COND_EXPR;
                rprec = COND_PREC;
                next_prec = COND_PREC;

                if (prec > rprec)
                    return lhs_expr;

                parse->pos++;
                struct ast *rhs1_expr = parse_expr(parse);
                if (rhs1_expr == NULL)
                    goto err1;

                expect(parse, ':');
                struct ast *rhs2_expr = parse_binop_expr(parse, COND_PREC);
                if (rhs2_expr == NULL)
                    goto err1;

                lhs_expr = ast_new_ast(line, op, 3, lhs_expr, rhs1_expr, rhs2_expr);
                continue;

            case IDENT_TOK:
                goto err1;

            default:
                return lhs_expr;
        }

        if (prec > rprec)
            return lhs_expr;

        parse->pos++;

        struct ast *rhs_expr = parse_binop_expr(parse, next_prec);
        if (rhs_expr == NULL)
            goto err1;

        lhs_expr = ast_new_ast(line, op, 2, lhs_expr, rhs_expr);
    }

err1:
    ast_unref(lhs_expr);
err0:
    return NULL;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %esi, %ebx
movq %rdi, %r14
callq 0xa45a
testq %rax, %rax
je 0xa17b
movq %rax, %r15
movq (%r14), %rcx
movslq 0x14(%r14), %rax
movq %rax, %rdx
shlq $0x5, %rdx
cmpl $0x101, (%rcx,%rdx)     # imm = 0x101
jne 0xa17e
movq 0x8(%rcx,%rdx), %r13
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
callq 0x9d3a
movq %rax, %r12
testq %rax, %rax
je 0xa16e
movl $0x2, %edx
movq %r13, %rdi
movl $0x42e0, %esi           # imm = 0x42E0
movq %r15, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0x2532
movq %rax, %r15
testq %r12, %r12
jne 0xa17e
movq %r15, %rdi
callq 0x26cf
xorl %r15d, %r15d
testq %r15, %r15
je 0xa443
movq (%r14), %rcx
movslq 0x14(%r14), %rax
movq %rax, %rdx
shlq $0x5, %rdx
movq 0x8(%rcx,%rdx), %r13
movl (%rcx,%rdx), %ecx
movl $0x6, %r12d
cmpl $0x109, %ecx            # imm = 0x109
jle 0xa1de
addl $0xfffffef6, %ecx       # imm = 0xFFFFFEF6
cmpl $0x16, %ecx
ja 0xa3d3
leaq 0x450b(%rip), %rdx      # 0xe6cc
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movl $0x4240, %ebp           # imm = 0x4240
movl $0x4, %ecx
movl $0x5, %esi
jmp 0xa3cf
leal -0x25(%rcx), %edx
cmpl $0x1a, %edx
ja 0xa200
leaq 0x4473(%rip), %rsi      # 0xe660
movslq (%rsi,%rdx,4), %rcx
addq %rsi, %rcx
jmpq *%rcx
movl $0x42c2, %ebp           # imm = 0x42C2
jmp 0xa2ee
cmpl $0x7c, %ecx
je 0xa424
cmpl $0x7e, %ecx
jne 0xa3d3
movl $0x4280, %ebp           # imm = 0x4280
movl $0x8, %ecx
movl $0x9, %esi
jmp 0xa3cf
movl $0x42b1, %ebp           # imm = 0x42B1
jmp 0xa2da
movl $0x4200, %ebp           # imm = 0x4200
movl $0x1, %esi
xorl %ecx, %ecx
jmp 0xa3cf
movl $0x42c0, %ebp           # imm = 0x42C0
jmp 0xa2ee
cmpl $0x2, %ebx
jg 0xa3d3
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
xorl %esi, %esi
callq 0xa102
testq %rax, %rax
je 0xa40f
movq %rax, %rbp
movq (%r14), %rcx
movslq 0x14(%r14), %rax
movq %rax, %rdx
shlq $0x5, %rdx
cmpl $0x3a, (%rcx,%rdx)
jne 0xa28a
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
movl $0x2, %esi
callq 0xa102
testq %rax, %rax
je 0xa40f
movl $0x3, %edx
movq %r13, %rdi
movl $0x4210, %esi           # imm = 0x4210
movq %r15, %rcx
movq %rbp, %r8
movq %rax, %r9
xorl %eax, %eax
callq 0x2532
movq %rax, %r15
movl $0x4, %r12d
jmp 0xa40f
movl $0x4261, %ebp           # imm = 0x4261
jmp 0xa384
movl $0x42b0, %ebp           # imm = 0x42B0
movl $0xb, %ecx
movl $0xc, %esi
jmp 0xa3cf
movl $0x42c1, %ebp           # imm = 0x42C1
movl $0xc, %ecx
movl $0xd, %esi
jmp 0xa3cf
movl $0x4290, %ebp           # imm = 0x4290
movl $0x9, %ecx
movl $0xa, %esi
jmp 0xa3cf
movl $0x4260, %ebp           # imm = 0x4260
jmp 0xa384
movl $0x4220, %ebp           # imm = 0x4220
jmp 0xa3c5
movl $0x42a0, %ebp           # imm = 0x42A0
jmp 0xa3a6
movl $0x4226, %ebp           # imm = 0x4226
jmp 0xa3c5
movl $0x4251, %ebp           # imm = 0x4251
jmp 0xa395
movl $0x4229, %ebp           # imm = 0x4229
jmp 0xa3c5
movl $0x4263, %ebp           # imm = 0x4263
jmp 0xa384
movl $0x422a, %ebp           # imm = 0x422A
jmp 0xa3c5
movl $0x4225, %ebp           # imm = 0x4225
jmp 0xa3c5
movl $0x4230, %ebp           # imm = 0x4230
movl $0x3, %ecx
movl $0x4, %esi
jmp 0xa3cf
movl $0x4227, %ebp           # imm = 0x4227
jmp 0xa3c5
movl $0x4222, %ebp           # imm = 0x4222
jmp 0xa3c5
movl $0x4223, %ebp           # imm = 0x4223
jmp 0xa3c5
movl $0x4262, %ebp           # imm = 0x4262
movl $0x6, %ecx
movl $0x7, %esi
jmp 0xa3cf
movl $0x4250, %ebp           # imm = 0x4250
movl $0x5, %ecx
movl $0x6, %esi
jmp 0xa3cf
movl $0x42a1, %ebp           # imm = 0x42A1
movl $0xa, %ecx
movl $0xb, %esi
jmp 0xa3cf
movl $0x4224, %ebp           # imm = 0x4224
jmp 0xa3c5
movl $0x4221, %ebp           # imm = 0x4221
jmp 0xa3c5
movl $0x4228, %ebp           # imm = 0x4228
movl $0x1, %esi
movl $0x1, %ecx
cmpl %ebx, %ecx
jge 0xa3df
movl $0x1, %r12d
movq %r15, (%rsp)
jmp 0xa40f
incl %eax
movl %eax, 0x14(%r14)
movq %r14, %rdi
callq 0xa102
testq %rax, %rax
je 0xa40f
xorl %r12d, %r12d
movl $0x2, %edx
movq %r13, %rdi
movl %ebp, %esi
movq %r15, %rcx
movq %rax, %r8
xorl %eax, %eax
callq 0x2532
movq %rax, %r15
testl %r12d, %r12d
je 0xa187
cmpl $0x4, %r12d
je 0xa187
jmp 0xa435
movl $0x4270, %ebp           # imm = 0x4270
movl $0x7, %ecx
movl $0x8, %esi
jmp 0xa3cf
cmpl $0x6, %r12d
jne 0xa447
movq %r15, %rdi
callq 0x26cf
xorl %eax, %eax
jmp 0xa44b
movq (%rsp), %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq