// File: /workspace/github_c_makefile_star2_O0/michaelforney[P]cproc/expr.c
// Function: mkbinaryexpr
static struct expr *
mkbinaryexpr(struct location *loc, enum tokenkind op, struct expr *l, struct expr *r)
{
	struct expr *e;
	struct type *t = NULL;
	enum typeprop lp, rp;

	lp = l->type->prop;
	rp = r->type->prop;
	switch (op) {
	case TLOR:
	case TLAND:
		if (!(lp & PROPSCALAR))
			error(loc, "left operand of '%s' operator must be scalar", tokstr[op]);
		if (!(rp & PROPSCALAR))
			error(loc, "right operand of '%s' operator must be scalar", tokstr[op]);
		t = &typeint;
		break;
	case TEQL:
	case TNEQ:
		t = &typeint;
		if (lp & PROPARITH && rp & PROPARITH) {
			commonreal(&l, &r);
			break;
		}
		if (l->type->kind != TYPEPOINTER)
			e = l, l = r, r = e;
		if (l->type->kind != TYPEPOINTER)
			error(loc, "invalid operands to '%s' operator", tokstr[op]);
		if (nullpointer(eval(r))) {
			r = exprconvert(r, l->type);
			break;
		}
		if (nullpointer(eval(l))) {
			l = exprconvert(l, r->type);
			break;
		}
		if (r->type->kind != TYPEPOINTER)
			error(loc, "invalid operands to '%s' operator", tokstr[op]);
		if (l->type->base->kind == TYPEVOID)
			e = l, l = r, r = e;
		if (r->type->base->kind == TYPEVOID && l->type->base->kind != TYPEFUNC)
			r = exprconvert(r, l->type);
		else if (!typecompatible(l->type->base, r->type->base))
			error(loc, "pointer operands to '%s' operator are to incompatible types", tokstr[op]);
		break;
	case TLESS:
	case TGREATER:
	case TLEQ:
	case TGEQ:
		t = &typeint;
		if (lp & PROPREAL && rp & PROPREAL) {
			commonreal(&l, &r);
		} else if (l->type->kind == TYPEPOINTER && r->type->kind == TYPEPOINTER) {
			if (!typecompatible(l->type->base, r->type->base) || l->type->base->kind == TYPEFUNC)
				error(loc, "pointer operands to '%s' operator must be to compatible object types", tokstr[op]);
		} else {
			error(loc, "invalid operands to '%s' operator", tokstr[op]);
		}
		break;
	case TBOR:
	case TXOR:
	case TBAND:
		t = commonreal(&l, &r);
		break;
	case TADD:
		if (lp & PROPARITH && rp & PROPARITH) {
			t = commonreal(&l, &r);
			break;
		}
		if (r->type->kind == TYPEPOINTER)
			e = l, l = r, r = e, rp = lp;
		if (l->type->kind != TYPEPOINTER || !(rp & PROPINT))
			error(loc, "invalid operands to '+' operator");
		t = l->type;
		if (t->base->incomplete || t->base->kind == TYPEFUNC)
			error(loc, "pointer operand to '+' must be to complete object type");
		r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size));
		break;
	case TSUB:
		if (lp & PROPARITH && rp & PROPARITH) {
			t = commonreal(&l, &r);
			break;
		}
		if (l->type->kind != TYPEPOINTER || !(rp & PROPINT) && r->type->kind != TYPEPOINTER)
			error(loc, "invalid operands to '-' operator");
		if (l->type->base->incomplete || l->type->base->kind == TYPEFUNC)
			error(loc, "pointer operand to '-' must be to complete object type");
		if (rp & PROPINT) {
			t = l->type;
			r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size));
		} else {
			if (!typecompatible(l->type->base, r->type->base))
				error(&tok.loc, "pointer operands to '-' are to incompatible types");
			op = TDIV;
			t = &typelong;
			e = mkbinaryexpr(loc, TSUB, exprconvert(l, &typelong), exprconvert(r, &typelong));
			r = mkconstexpr(&typelong, l->type->base->size);
			l = e;
		}
		break;
	case TMOD:
		if (!(lp & PROPINT) || !(rp & PROPINT))
			error(loc, "operands to '%%' operator must be integer");
		t = commonreal(&l, &r);
		break;
	case TMUL:
	case TDIV:
		if (!(lp & PROPARITH) || !(rp & PROPARITH))
			error(loc, "operands to '%s' operator must be arithmetic", tokstr[op]);
		t = commonreal(&l, &r);
		break;
	case TSHL:
	case TSHR:
		if (!(lp & PROPINT) || !(rp & PROPINT))
			error(loc, "operands to '%s' operator must be integer", tokstr[op]);
		l = exprpromote(l);
		r = exprpromote(r);
		t = l->type;
		break;
	default:
		fatal("internal error: unknown binary operator %d", op);
	}
	e = mkexpr(EXPRBINARY, t, NULL);
	e->op = op;
	e->u.binary.l = l;
	e->u.binary.r = r;

	return e;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x34(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
movl %eax, -0x38(%rbp)
movl -0xc(%rbp), %eax
addl $-0x4a, %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x13, %eax
ja 0x9d1a
movq -0x40(%rbp), %rax
leaq 0xfe71(%rip), %rcx      # 0x194bc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl -0x34(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
jne 0x9681
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x18041(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10f30(%rip), %rsi     # 0x1a5aa
movb $0x0, %al
callq 0x11190
movl -0x38(%rbp), %eax
andl $0x10, %eax
cmpl $0x0, %eax
jne 0x96ae
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x18014(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10f30(%rip), %rsi     # 0x1a5d7
movb $0x0, %al
callq 0x11190
leaq 0x185eb(%rip), %rax     # 0x21ca0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
leaq 0x185db(%rip), %rax     # 0x21ca0
movq %rax, -0x30(%rbp)
movl -0x34(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x96f1
movl -0x38(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x96f1
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
jmp 0x9d2b
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
je 0x9716
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
je 0x9745
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17f7d(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10ec7(%rip), %rsi     # 0x1a605
movb $0x0, %al
callq 0x11190
movq -0x20(%rbp), %rdi
callq 0x7010
movq %rax, %rdi
callq 0x8210
testb $0x1, %al
jne 0x975c
jmp 0x9776
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8290
movq %rax, -0x20(%rbp)
jmp 0x9d2b
movq -0x18(%rbp), %rdi
callq 0x7010
movq %rax, %rdi
callq 0x8210
testb $0x1, %al
jne 0x978d
jmp 0x97a7
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8290
movq %rax, -0x18(%rbp)
jmp 0x9d2b
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
je 0x97d6
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17eec(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10e36(%rip), %rsi     # 0x1a605
movb $0x0, %al
callq 0x11190
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0x1, (%rax)
jne 0x97ff
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0x1, (%rax)
jne 0x9838
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0xe, (%rax)
je 0x9838
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x8290
movq %rax, -0x20(%rbp)
jmp 0x987d
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rsi
callq 0x11890
testb $0x1, %al
jne 0x987b
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17e47(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10db3(%rip), %rsi     # 0x1a627
movb $0x0, %al
callq 0x11190
jmp 0x987d
jmp 0x9d2b
leaq 0x18417(%rip), %rax     # 0x21ca0
movq %rax, -0x30(%rbp)
movl -0x34(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x98b5
movl -0x38(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x98b5
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
jmp 0x994b
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x9927
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x9927
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rsi
callq 0x11890
testb $0x1, %al
jne 0x98f2
jmp 0x9903
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0xe, (%rax)
jne 0x9925
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17d9d(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10d45(%rip), %rsi     # 0x1a663
movb $0x0, %al
callq 0x11190
jmp 0x9949
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17d79(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10cc3(%rip), %rsi     # 0x1a605
movb $0x0, %al
callq 0x11190
jmp 0x994b
jmp 0x9d2b
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movl -0x34(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x9992
movl -0x38(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x9992
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x99bd
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x99d5
movl -0x38(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x99e7
movq -0x8(%rbp), %rdi
leaq 0x10cc8(%rip), %rsi     # 0x1a6a8
movb $0x0, %al
callq 0x11190
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
testb $0x1, 0x3c(%rax)
jne 0x9a0e
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
cmpl $0xe, (%rax)
jne 0x9a20
movq -0x8(%rbp), %rdi
leaq 0x10cb0(%rip), %rsi     # 0x1a6c9
movb $0x0, %al
callq 0x11190
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x18375(%rip), %rsi     # 0x21da8
callq 0x8290
movq %rax, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rsi
leaq 0x18359(%rip), %rdi     # 0x21da8
callq 0xb820
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rdx
movq %rax, %rcx
movl $0x4b, %esi
callq 0x95f0
movq %rax, -0x20(%rbp)
jmp 0x9d2b
movl -0x34(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x9a9e
movl -0x38(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x9a9e
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x9ac3
movl -0x38(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x9ad5
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
je 0x9ad5
movq -0x8(%rbp), %rdi
leaq 0x10c32(%rip), %rsi     # 0x1a700
movb $0x0, %al
callq 0x11190
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
testb $0x1, 0x3c(%rax)
jne 0x9af8
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
cmpl $0xe, (%rax)
jne 0x9b0a
movq -0x8(%rbp), %rdi
leaq 0x10c1e(%rip), %rsi     # 0x1a721
movb $0x0, %al
callq 0x11190
movl -0x38(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x9b73
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x18274(%rip), %rsi     # 0x21da8
callq 0x8290
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rsi
leaq 0x18258(%rip), %rdi     # 0x21da8
callq 0xb820
movq -0x60(%rbp), %rdi
movq -0x58(%rbp), %rdx
movq %rax, %rcx
movl $0x4b, %esi
callq 0x95f0
movq %rax, -0x20(%rbp)
jmp 0x9c2c
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rdi
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rsi
callq 0x11890
testb $0x1, %al
jne 0x9bad
leaq 0x1860d(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x10bb2(%rip), %rsi     # 0x1a758
movb $0x0, %al
callq 0x11190
movl $0x50, -0xc(%rbp)
leaq 0x18195(%rip), %rax     # 0x21d50
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x18(%rbp), %rdi
leaq 0x1817e(%rip), %rsi     # 0x21d50
callq 0x8290
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x1816a(%rip), %rsi     # 0x21d50
callq 0x8290
movq -0x70(%rbp), %rdi
movq -0x68(%rbp), %rdx
movq %rax, %rcx
movl $0x4d, %esi
callq 0x95f0
movq %rax, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rsi
leaq 0x18135(%rip), %rdi     # 0x21d50
callq 0xb820
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x9d2b
movl -0x34(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x9c47
movl -0x38(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x9c59
movq -0x8(%rbp), %rdi
leaq 0x10b38(%rip), %rsi     # 0x1a78a
movb $0x0, %al
callq 0x11190
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movl -0x34(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x9c85
movl -0x38(%rbp), %eax
andl $0x8, %eax
cmpl $0x0, %eax
jne 0x9ca7
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x17a1b(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10b14(%rip), %rsi     # 0x1a7b4
movb $0x0, %al
callq 0x11190
leaq -0x18(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x8fa0
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movl -0x34(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x9cd0
movl -0x38(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
jne 0x9cf2
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %eax
movl %eax, %ecx
leaq 0x179d0(%rip), %rax     # 0x216b0
movq (%rax,%rcx,8), %rdx
leaq 0x10af6(%rip), %rsi     # 0x1a7e1
movb $0x0, %al
callq 0x11190
movq -0x18(%rbp), %rdi
callq 0x82f0
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rdi
callq 0x82f0
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x9d2b
movl -0xc(%rbp), %esi
leaq 0x10ae7(%rip), %rdi     # 0x1a80b
movb $0x0, %al
callq 0x12650
movq -0x30(%rbp), %rsi
movl $0x9, %edi
xorl %eax, %eax
movl %eax, %edx
callq 0x9040
movq %rax, -0x28(%rbp)
movl -0xc(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x18(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x28(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)