// File: /workspace/github_c_makefile_star2_O1/oridb[P]mc/mi/flatten.c
// Function: rval
static Node *
rval(Flattenctx *s, Node *n)
{
	Node *t, *u, *v; /* temporary nodes */
	Node *r; /* expression result */
	Node **args;
	Type *ty;

	const Op fusedmap[Numops] = {
		[Oaddeq]	= Oadd,
		[Osubeq]	= Osub,
		[Omuleq]	= Omul,
		[Odiveq]	= Odiv,
		[Omodeq]	= Omod,
		[Oboreq]	= Obor,
		[Obandeq]	= Oband,
		[Obxoreq]	= Obxor,
		[Obsleq]	= Obsl,
		[Obsreq]	= Obsr,
	};

	r = NULL;
	args = n->expr.args;
	switch (exprop(n)) {
	case Oauto:
		t = temp(s, n);
		r = assign(s, t, n->expr.args[0]);
		lappend(&s->curst->autotmp, &s->curst->nautotmp, t);
		break;
	case Osize:
		r = n;	/* don't touch subexprs; they're a pseudo decl */
		break;
	case Olor: case Oland:
		r = flattenlazy(s, n);
		break;
	case Oidx:
		t = rval(s, n->expr.args[0]);
		u = rval(s, n->expr.args[1]);
		r = mkexpr(n->loc, Oidx, t, u, NULL);
		r->expr.type = n->expr.type;
		break;
		/* array.len slice.len are magic 'virtual' members.
		 * they need to be special cased. */
	case Omemb:
                ty = tybase(exprtype(args[0]));
		if (ty->type == Tyslice || ty->type == Tyarray) {
			r = seqlen(s, args[0], exprtype(n));
		} else {
	case Otupmemb:
			t = rval(s, args[0]);
			r = mkexpr(n->loc, exprop(n), t, args[1], NULL);
			r->expr.type = n->expr.type;
		}
		break;
	case Oucon:
		if (n->expr.nargs > 1)
			t = rval(s, args[1]);
		else
			t = NULL;
		r = mkexpr(n->loc, Oucon, args[0], t, NULL);
		r->expr.type = n->expr.type;
		break;
	/* fused ops:
	 * foo ?= blah
	 *    =>
	 *     foo = foo ? blah*/
	case Oaddeq: case Osubeq: case Omuleq: case Odiveq: case Omodeq:
	case Oboreq: case Obandeq: case Obxoreq: case Obsleq: case Obsreq:
		assert(fusedmap[exprop(n)] != Obad);
		u = lval(s, args[0]);
		v = rval(s, args[1]);
		v = mkexpr(n->loc, fusedmap[exprop(n)], u, v, NULL);
		v->expr.type = u->expr.type;
		r = asn(u, v);
		break;

	/* ++expr(x)
	 *  => args[0] = args[0] + 1
	 *     expr(x) */
	case Opreinc:
		t = lval(s, args[0]);
		v = asn(t, addk(t, 1));
		append(s, v);
		r = rval(s, t);
		break;
	case Opredec:
		t = lval(s, args[0]);
		v = asn(t, subk(t, 1));
		append(s, v);
		r = rval(s, t);
		break;

	/* expr(x++)
	 *   => expr
	 *      x = x + 1
	 */
	case Opostinc:
		r = lval(s, args[0]);
		t = asn(r, addk(r, 1));
		lappend(&s->incqueue, &s->nqueue, t);
		break;
	case Opostdec:
		r = lval(s, args[0]);
		t = asn(r, subk(r, 1));
		lappend(&s->incqueue, &s->nqueue, t);
		break;
	case Olit:
		switch (args[0]->lit.littype) {
		case Lvoid:
		case Lchr:
		case Lbool:
		case Llbl:
		case Lint:
		case Lstr:
		case Lflt:
		case Lfunc:
			r = n; //capture(s, n, dst);
			break;
		}
		break;
	case Ovar:
		r = n;
		break;;
	case Oret:
		v = rval(s, args[0]);
		if (!s->tret)
			s->tret = temp(s, v);
		flatten(s, asn(lval(s, s->tret), v));
		draininc(s);
		if (exitscope(s, NULL, Zloc, Xret))
			append(s, mkexpr(n->loc, Oret, s->tret, NULL));
		break;
	case Otern:
		r = flattentern(s, n);
		break;
	case Oasn:
		r = assign(s, args[0], args[1]);
		break;
	case Obreak:
		r = NULL;
		if (s->inloop == 0)
			fatal(n, "trying to break when not in loop");
		if (exitscope(s, s->loop.body, n->loc, Xbrk))
			jmp(s, s->loop.lbrk);
		break;
	case Ocontinue:
		r = NULL;
		if (s->inloop == 0)
			fatal(n, "trying to continue when not in loop");
		if (exitscope(s, s->loop.body, n->loc, Xcnt))
			jmp(s, s->loop.lcnt);
		break;
	case Oeq: case One:
		r = compare(s, n, 1);
		break;
	case Ogt: case Oge: case Olt: case Ole:
		r = compare(s, n, 0);
		break;
	default:
		if (istyfloat(exprtype(n))) {
			switch (exprop(n)) {
			case Oadd:	n->expr.op = Ofadd;	break;
			case Osub:	n->expr.op = Ofsub;	break;
			case Omul:	n->expr.op = Ofmul;	break;
			case Odiv:	n->expr.op = Ofdiv;	break;
			default:	break;
			}
		}
		r = visit(s, n);
		break;
	}
	if (r && n->expr.idx)
		r->expr.idx = n->expr.idx;
	return r;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
movq 0x50(%rsi), %r12
movq %rsi, %rdi
callq 0x1d672
decl %eax
cmpl $0x39, %eax
ja 0x29c8d
leaq 0xeb44(%rip), %rcx      # 0x382c0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rbx, %r15
jmpq *%rax
movq %rbx, %rdi
callq 0x1d672
movl %eax, %eax
leaq 0xec57(%rip), %r13      # 0x383f0
cmpl $0x0, (%r13,%rax,4)
je 0x29d0e
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %r15
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x2974d
movq %rax, %r14
movq %rbx, %rdi
callq 0x1d672
movl %eax, %eax
movl (%r13,%rax,4), %esi
movq (%rbx), %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1d832
movq 0x20(%r15), %rcx
movq %rcx, 0x20(%rax)
movq %r15, %rdi
movq %rax, %rsi
callq 0x2a2d9
jmp 0x29cc2
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
jmp 0x29813
movq %r14, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0x2a66e
jmp 0x29cc2
movq %rbx, %rdi
callq 0x2a4e0
movq %rax, %r15
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %r12
movq %r14, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x29f7d
movq %r14, %rdi
movq %rbp, %rsi
callq 0x2970a
movq (%rbx), %rdi
movl $0x1, %esi
callq 0x1e417
movq (%rbx), %rdi
movl $0x35, %esi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d832
movq %rax, %rbp
movq (%rbx), %rdi
movl $0x2, %esi
callq 0x22d38
movq %rax, 0x20(%rbp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x2a2d9
movq %r14, %rdi
movq %rax, %rsi
callq 0x2970a
movq %r14, %rdi
movq %r12, %rsi
callq 0x29e99
movq %r14, %rdi
movq %r13, %rsi
callq 0x2970a
movq (%rbx), %rdi
xorl %esi, %esi
callq 0x1e417
movq (%rbx), %rdi
movl $0x35, %esi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d832
movq %rax, %r13
movq (%rbx), %rdi
movl $0x2, %esi
callq 0x22d38
movq %rax, 0x20(%r13)
movq %r15, %rdi
movq %r13, %rsi
callq 0x2a2d9
movq %r14, %rdi
movq %rax, %rsi
callq 0x2970a
movq %r14, %rdi
movq %r12, %rsi
callq 0x29e99
jmp 0x29c3d
cmpq $0x2, 0x40(%rbx)
jb 0x29ce9
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x2974d
movq %rax, %rcx
jmp 0x29ceb
movq (%r12), %rdi
callq 0x1e5d4
movq %rax, %rdi
callq 0x22c44
movl (%rax), %eax
andl $-0x2, %eax
cmpl $0x14, %eax
jne 0x29978
movq (%r12), %r15
movq %rbx, %rdi
callq 0x1e5d4
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2a39e
jmp 0x29cc2
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2974d
movq %rax, %r14
movq %rbx, %rdi
callq 0x1d672
movq 0x8(%r12), %rcx
movq (%rbx), %rdi
movl %eax, %esi
movq %r14, %rdx
jmp 0x29cf7
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2974d
movq %rax, %r15
cmpq $0x0, 0x18(%r14)
jne 0x299c3
movq %r15, %rdi
callq 0x2a4e0
movq %rax, 0x18(%r14)
movq 0x18(%r14), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %rdi
movq %r15, %rsi
callq 0x2a2d9
movq %r14, %rdi
movq %rax, %rsi
callq 0x28f37
movq %r14, %rdi
callq 0x2a026
xorl %r15d, %r15d
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %r14, %rdi
xorl %esi, %esi
movl $0x2, %ecx
callq 0x29d47
testl %eax, %eax
je 0x29cc5
movq 0x18(%r14), %rdx
movq (%rbx), %rdi
xorl %r15d, %r15d
movl $0x2f, %esi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d832
movq %r14, %rdi
movq %rax, %rsi
jmp 0x29c43
cmpl $0x0, 0x48(%r14)
je 0x29d2d
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
xorl %r15d, %r15d
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x29d47
testl %eax, %eax
je 0x29cc5
movq 0x30(%r14), %rsi
jmp 0x29b3c
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %r15
movq %rax, %rdi
callq 0x2a623
jmp 0x29aab
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %r15
movq %rax, %rdi
callq 0x2a353
jmp 0x29b63
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %r15
movq %rax, %rdi
callq 0x2a353
movq %r15, %rdi
movq %rax, %rsi
callq 0x2a2d9
leaq 0x20(%r14), %rdi
addq $0x28, %r14
movq %r14, %rsi
movq %rax, %rdx
jmp 0x29af5
movq %rbx, %rdi
callq 0x2a4e0
movq %rax, %r12
movq 0x50(%rbx), %rax
movq (%rax), %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x2a517
movq %rax, %r15
movq 0x50(%r14), %rsi
leaq 0x50(%rsi), %rdi
addq $0x58, %rsi
movq %r12, %rdx
callq 0x2d3ff
jmp 0x29cc5
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %r14, %rdi
callq 0x2a517
jmp 0x29cc2
cmpl $0x0, 0x48(%r14)
je 0x29d36
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
movq %r14, %rdi
movl $0x1, %ecx
callq 0x29d47
testl %eax, %eax
je 0x29b44
movq 0x38(%r14), %rsi
movq %r14, %rdi
callq 0x29e99
xorl %r15d, %r15d
jmp 0x29cc5
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a5a2
movq %rax, %r15
movq %rax, %rdi
callq 0x2a623
movq %r15, %rdi
movq %rax, %rsi
callq 0x2a2d9
movq %r14, %rdi
movq %rax, %rsi
callq 0x2970a
movq %r14, %rdi
movq %r15, %rsi
callq 0x2974d
jmp 0x29cc2
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1e053
movq %rax, %r12
movq %rbx, %rdi
callq 0x2a4e0
movq %rax, %r15
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x29f7d
movq %r14, %rdi
movq %rbp, %rsi
callq 0x2970a
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x2974d
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2a517
movq %r14, %rdi
movq %rax, %rsi
callq 0x2970a
movq %r14, %rdi
movq %r12, %rsi
callq 0x29e99
movq %r14, %rdi
movq %r13, %rsi
callq 0x2970a
movq 0x50(%rbx), %rax
movq 0x10(%rax), %rsi
movq %r14, %rdi
callq 0x2974d
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2a517
movq %r14, %rdi
movq %rax, %rsi
callq 0x2970a
movq %r14, %rdi
movq %r12, %rsi
callq 0x2970a
jmp 0x29cc5
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x2974d
movq %rax, %r15
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x2974d
movq (%rbx), %rdi
movl $0x28, %esi
movq %r15, %rdx
movq %rax, %rcx
jmp 0x29cf7
movq (%r12), %rax
xorl %r15d, %r15d
cmpl $0x8, 0x18(%rax)
cmovbq %rbx, %r15
jmp 0x29cc5
movq %rbx, %rdi
callq 0x1e5d4
movq %rax, %rdi
callq 0x234b0
testl %eax, %eax
je 0x29cb7
movq %rbx, %rdi
callq 0x1d672
leal -0x2(%rax), %ecx
cmpl $0x3, %ecx
ja 0x29cb7
addl $0x4d, %eax
movl %eax, 0x18(%rbx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2a8c4
movq %rax, %r15
testq %r15, %r15
je 0x29cd7
movq 0x48(%rbx), %rax
testq %rax, %rax
je 0x29cd7
movq %rax, 0x48(%r15)
movq %r15, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %ecx, %ecx
movq (%r12), %rdx
movq (%rbx), %rdi
movl $0x36, %esi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1d832
movq %rax, %r15
movq 0x20(%rbx), %rax
movq %rax, 0x20(%r15)
jmp 0x29cc5
leaq 0xed98(%rip), %rdi      # 0x38aad
leaq 0xed0d(%rip), %rsi      # 0x38a29
leaq 0xeda6(%rip), %rcx      # 0x38ac9
movl $0x23d, %edx            # imm = 0x23D
callq 0x4180
leaq 0xedd7(%rip), %rsi      # 0x38b0b
jmp 0x29d3d
leaq 0xedad(%rip), %rsi      # 0x38aea
movq %rbx, %rdi
xorl %eax, %eax
callq 0x13aa3