// File: /workspace/github_c_makefile_star2_O0/michaelforney[P]cproc/eval.c
// Function: eval
struct expr *
eval(struct expr *expr)
{
	struct expr *l, *r, *c;
	struct decl *d;
	struct type *t;

	t = expr->type;
	switch (expr->kind) {
	case EXPRIDENT:
		d = expr->u.ident.decl;
		if (d->kind != DECLCONST)
			break;
		expr->kind = EXPRCONST;
		expr->u.constant.u = d->u.enumconst;
		break;
	case EXPRCOMPOUND:
		d = expr->u.compound.decl;
		if (d->u.obj.storage != SDSTATIC)
			break;
		d->value = mkglobal(d);
		emitdata(d, expr->u.compound.init);
		expr->kind = EXPRIDENT;
		expr->u.ident.decl = d;
		break;
	case EXPRUNARY:
		l = eval(expr->base);
		switch (expr->op) {
		case TBAND:
			switch (l->kind) {
			case EXPRUNARY:
				if (l->op == TMUL)
					expr = eval(l->base);
				break;
			case EXPRSTRING:
				l->u.ident.decl = stringdecl(l);
				l->kind = EXPRIDENT;
				expr->base = l;
				break;
			}
			break;
		case TMUL:
			break;
		default:
			if (l->kind != EXPRCONST)
				break;
			unary(expr, expr->op, l);
			break;
		}
		break;
	case EXPRCAST:
		l = eval(expr->base);
		if (l->kind == EXPRCONST) {
			expr->kind = EXPRCONST;
			if (l->type->prop & PROPINT && t->prop & PROPFLOAT) {
				if (l->type->u.basic.issigned)
					expr->u.constant.f = l->u.constant.i;
				else
					expr->u.constant.f = l->u.constant.u;
			} else if (l->type->prop & PROPFLOAT && t->prop & PROPINT) {
				if (t->u.basic.issigned) {
					if (l->u.constant.f < -0x1p63 || l->u.constant.f >= 0x1p63)
						error(&tok.loc, "integer part of floating-point constant %g cannot be represented as signed integer", l->u.constant.f);
					expr->u.constant.i = l->u.constant.f;
				} else {
					if (l->u.constant.f < 0.0 || l->u.constant.f >= 0x1p64)
						error(&tok.loc, "integer part of floating-point constant %g cannot be represented as unsigned integer", l->u.constant.f);
					expr->u.constant.u = l->u.constant.f;
				}
			} else {
				expr->u.constant = l->u.constant;
			}
			cast(expr);
		} else if (l->type->kind == TYPEPOINTER) {
			/*
			A cast from a pointer to integer is not a valid constant
			expression, but C11 allows implementations to recognize
			other forms of constant expressions (6.6p10), and some
			programs expect this functionality.
			*/
			if (t->kind == TYPEPOINTER || t->prop & PROPINT && t->size == typelong.size)
				expr = l;
		}
		break;
	case EXPRBINARY:
		l = eval(expr->u.binary.l);
		r = eval(expr->u.binary.r);
		expr->u.binary.l = l;
		expr->u.binary.r = r;
		switch (expr->op) {
		case TADD:
			if (r->kind == EXPRBINARY)
				c = l, l = r, r = c;
			/* fallthrough */
		case TSUB:
			if (r->kind != EXPRCONST)
				break;
			if (l->kind == EXPRCONST) {
				binary(expr, expr->op, l, r);
			} else if (l->kind == EXPRBINARY && l->type->kind == TYPEPOINTER && l->op == TADD && l->u.binary.r->kind == EXPRCONST) {
				/* (P + C1) ± C2  ->  P + (C1 ± C2) */
				binary(expr->u.binary.r, expr->op, l->u.binary.r, r);
				expr->op = TADD;
				expr->u.binary.l = l->u.binary.l;
			}
			break;
		case TLOR:
			if (l->kind != EXPRCONST)
				break;
			return l->u.constant.u ? l : r;
		case TLAND:
			if (l->kind != EXPRCONST)
				break;
			return l->u.constant.u ? r : l;
		default:
			if (l->kind != EXPRCONST || r->kind != EXPRCONST)
				break;
			binary(expr, expr->op, l, r);
		}
		break;
	}

	return expr;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x40(%rbp)
subq $0x9, %rax
ja 0x757b
movq -0x40(%rbp), %rax
leaq 0x12119(%rip), %rcx     # 0x19160
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x3, 0x8(%rax)
je 0x706b
jmp 0x757b
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movq -0x30(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x757b
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x44(%rax)
je 0x70a5
jmp 0x757b
movq -0x30(%rbp), %rdi
callq 0x12c00
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x169a0
movq -0x10(%rbp), %rax
movl $0x0, (%rax)
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x757b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x7010
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x14(%rax), %eax
movl %eax, -0x44(%rbp)
subl $0x4a, %eax
je 0x7111
jmp 0x7107
movl -0x44(%rbp), %eax
subl $0x4b, %eax
je 0x7174
jmp 0x7176
movq -0x18(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x48(%rbp)
subl $0x2, %eax
je 0x7148
jmp 0x7121
movl -0x48(%rbp), %eax
subl $0x7, %eax
jne 0x7172
jmp 0x712b
movq -0x18(%rbp), %rax
cmpl $0x4b, 0x14(%rax)
jne 0x7146
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x7010
movq %rax, -0x10(%rbp)
jmp 0x7172
movq -0x18(%rbp), %rdi
callq 0x5440
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rax
movl $0x0, (%rax)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x18(%rax)
jmp 0x7195
jmp 0x7195
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
je 0x7181
jmp 0x7195
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x14(%rax), %esi
movq -0x18(%rbp), %rdx
callq 0x7590
jmp 0x757b
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x7010
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x7371
movq -0x10(%rbp), %rax
movl $0x1, (%rax)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x7240
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x7240
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
testb $0x1, 0x40(%rax)
je 0x7207
movq -0x18(%rbp), %rax
cvtsi2sdq 0x30(%rax), %xmm0
movq -0x10(%rbp), %rax
movsd %xmm0, 0x30(%rax)
jmp 0x723b
movq -0x18(%rbp), %rax
movq 0x30(%rax), %xmm0
movaps 0x11f29(%rip), %xmm1    # 0x19140
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x11f2d(%rip), %xmm1    # 0x19150
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movq -0x10(%rbp), %rax
movsd %xmm0, 0x30(%rax)
jmp 0x7366
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
movl 0x4(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x7354
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x7354
movq -0x38(%rbp), %rax
testb $0x1, 0x40(%rax)
je 0x72d4
movq -0x18(%rbp), %rax
movsd 0x11eb0(%rip), %xmm0    # 0x19130
ucomisd 0x30(%rax), %xmm0
ja 0x729e
movq -0x18(%rbp), %rax
movsd 0x30(%rax), %xmm0
movsd 0x11e90(%rip), %xmm1    # 0x19128
ucomisd %xmm1, %xmm0
jb 0x72c0
movq -0x18(%rbp), %rax
movsd 0x30(%rax), %xmm0
leaq 0x1aefa(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x11f17(%rip), %rsi     # 0x191d0
movb $0x1, %al
callq 0x11190
movq -0x18(%rbp), %rax
cvttsd2si 0x30(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x7352
movq -0x18(%rbp), %rax
xorps %xmm0, %xmm0
ucomisd 0x30(%rax), %xmm0
ja 0x72f9
movq -0x18(%rbp), %rax
movsd 0x30(%rax), %xmm0
movsd 0x11e2d(%rip), %xmm1    # 0x19120
ucomisd %xmm1, %xmm0
jb 0x731b
movq -0x18(%rbp), %rax
movsd 0x30(%rax), %xmm0
leaq 0x1ae9f(%rip), %rdi     # 0x221a8
addq $0x8, %rdi
leaq 0x11f0f(%rip), %rsi     # 0x19223
movb $0x1, %al
callq 0x11190
movq -0x18(%rbp), %rax
movsd 0x30(%rax), %xmm0
movsd 0x11dfc(%rip), %xmm2    # 0x19128
movaps %xmm0, %xmm1
subsd %xmm2, %xmm1
cvttsd2si %xmm1, %rax
cvttsd2si %xmm0, %rcx
movq %rcx, %rdx
sarq $0x3f, %rdx
andq %rdx, %rax
orq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x7364
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rcx
movq 0x30(%rcx), %rcx
movq %rcx, 0x30(%rax)
jmp 0x7366
movq -0x10(%rbp), %rdi
callq 0x7640
jmp 0x73b7
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x73b5
movq -0x38(%rbp), %rax
cmpl $0xc, (%rax)
je 0x73ab
movq -0x38(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x73b3
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
leaq 0x1a9ab(%rip), %rcx     # 0x21d50
cmpq 0x10(%rcx), %rax
jne 0x73b3
movq -0x18(%rbp), %rax
movq %rax, -0x10(%rbp)
jmp 0x73b5
jmp 0x73b7
jmp 0x757b
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x7010
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x7010
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rbp), %rax
movl 0x14(%rax), %eax
addl $-0x4c, %eax
movl %eax, %ecx
movq %rcx, -0x50(%rbp)
subl $0x11, %eax
ja 0x754d
movq -0x50(%rbp), %rax
leaq 0x11d6e(%rip), %rcx     # 0x19188
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x20(%rbp), %rax
cmpl $0x9, (%rax)
jne 0x7444
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x7446
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
je 0x7454
jmp 0x7579
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x7477
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x14(%rax), %esi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x7710
jmp 0x74e1
movq -0x18(%rbp), %rax
cmpl $0x9, (%rax)
jne 0x74df
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0xc, (%rax)
jne 0x74df
movq -0x18(%rbp), %rax
cmpl $0x4c, 0x14(%rax)
jne 0x74df
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x1, (%rax)
jne 0x74df
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x10(%rbp), %rax
movl 0x14(%rax), %esi
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rdx
movq -0x20(%rbp), %rcx
callq 0x7710
movq -0x10(%rbp), %rax
movl $0x4c, 0x14(%rax)
movq -0x18(%rbp), %rax
movq 0x30(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
jmp 0x74e1
jmp 0x7579
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
je 0x74f4
jmp 0x7579
movq -0x18(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x7509
movq -0x18(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x7511
movq -0x20(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x7583
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
je 0x7526
jmp 0x7579
movq -0x18(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x753b
movq -0x20(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x7543
movq -0x18(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x7583
movq -0x18(%rbp), %rax
cmpl $0x1, (%rax)
jne 0x755f
movq -0x20(%rbp), %rax
cmpl $0x1, (%rax)
je 0x7561
jmp 0x7579
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x14(%rax), %esi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0x7710
jmp 0x757b
movq -0x10(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)