// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rdi
callq 0xdf20
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0xda78
jmp 0xdf01
jmp 0xda7a
movq -0x10(%rbp), %rdi
callq 0xcb70
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
callq 0xcd10
movl (%rax), %eax
addl $-0x25, %eax
movl %eax, %ecx
movq %rcx, -0x58(%rbp)
subl $0xfb, %eax
ja 0xde92
movq -0x58(%rbp), %rax
leaq 0x659b(%rip), %rcx      # 0x1404c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x4200, -0x24(%rbp)    # imm = 0x4200
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4220, -0x24(%rbp)    # imm = 0x4220
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4221, -0x24(%rbp)    # imm = 0x4221
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4222, -0x24(%rbp)    # imm = 0x4222
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4223, -0x24(%rbp)    # imm = 0x4223
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4224, -0x24(%rbp)    # imm = 0x4224
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4225, -0x24(%rbp)    # imm = 0x4225
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4229, -0x24(%rbp)    # imm = 0x4229
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x422a, -0x24(%rbp)    # imm = 0x422A
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4226, -0x24(%rbp)    # imm = 0x4226
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4227, -0x24(%rbp)    # imm = 0x4227
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4228, -0x24(%rbp)    # imm = 0x4228
movl $0x1, -0x28(%rbp)
movl $0x1, -0x2c(%rbp)
jmp 0xde9c
movl $0x4240, -0x24(%rbp)    # imm = 0x4240
movl $0x4, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4230, -0x24(%rbp)    # imm = 0x4230
movl $0x3, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4250, -0x24(%rbp)    # imm = 0x4250
movl $0x5, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4251, -0x24(%rbp)    # imm = 0x4251
movl $0x5, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4260, -0x24(%rbp)    # imm = 0x4260
movl $0x6, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4261, -0x24(%rbp)    # imm = 0x4261
movl $0x6, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4262, -0x24(%rbp)    # imm = 0x4262
movl $0x6, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4263, -0x24(%rbp)    # imm = 0x4263
movl $0x6, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4270, -0x24(%rbp)    # imm = 0x4270
movl $0x7, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4280, -0x24(%rbp)    # imm = 0x4280
movl $0x8, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4290, -0x24(%rbp)    # imm = 0x4290
movl $0x9, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42a0, -0x24(%rbp)    # imm = 0x42A0
movl $0xa, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42a1, -0x24(%rbp)    # imm = 0x42A1
movl $0xa, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42b0, -0x24(%rbp)    # imm = 0x42B0
movl $0xb, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42b1, -0x24(%rbp)    # imm = 0x42B1
movl $0xb, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42c0, -0x24(%rbp)    # imm = 0x42C0
movl $0xc, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42c1, -0x24(%rbp)    # imm = 0x42C1
movl $0xc, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x42c2, -0x24(%rbp)    # imm = 0x42C2
movl $0xc, -0x28(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xde9c
movl $0x4210, -0x24(%rbp)    # imm = 0x4210
movl $0x2, -0x28(%rbp)
movl $0x2, -0x2c(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x28(%rbp), %eax
jle 0xde16
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xdf09
movq -0x10(%rbp), %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
movq -0x10(%rbp), %rdi
callq 0xd870
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0xde3c
jmp 0xdef8
movq -0x10(%rbp), %rdi
movl $0x3a, %esi
callq 0xda00
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0xda50
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0xde68
jmp 0xdef8
movq -0x38(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0x20(%rbp), %rcx
movq -0x40(%rbp), %r8
movq -0x48(%rbp), %r9
movl $0x3, %edx
movb $0x0, %al
callq 0x2510
movq %rax, -0x20(%rbp)
jmp 0xda7a
jmp 0xdef8
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xdf09
movl -0x14(%rbp), %eax
cmpl -0x28(%rbp), %eax
jle 0xdeae
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xdf09
movq -0x10(%rbp), %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
movq -0x10(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xda50
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0xded4
jmp 0xdef8
movq -0x38(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0x20(%rbp), %rcx
movq -0x50(%rbp), %r8
movl $0x2, %edx
movb $0x0, %al
callq 0x2510
movq %rax, -0x20(%rbp)
jmp 0xda7a
movq -0x20(%rbp), %rdi
callq 0x27e0
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)