// File: /workspace/github_c_makefile_star2_O2/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 0x1b5e6
decl %eax
cmpl $0x39, %eax
ja 0x266d8
leaq 0xe0d6(%rip), %rcx      # 0x342ac
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rbx, %r15
jmpq *%rax
movq %rbx, %rdi
callq 0x1b5e6
movl %eax, %eax
leaq 0xe1ed(%rip), %r13      # 0x343e0
cmpl $0x0, (%r13,%rax,4)
je 0x2675c
movq (%r12), %rsi
movq %r14, %rdi
callq 0x26f9c
movq %rax, %r15
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x261a7
movq %rax, %r14
movq %rbx, %rdi
callq 0x1b5e6
movl %eax, %eax
movl (%r13,%rax,4), %esi
movq (%rbx), %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1b718
movq 0x20(%r15), %rcx
movq %rcx, 0x20(%rax)
movq %r15, %rdi
movq %rax, %rsi
callq 0x26cf2
jmp 0x2670d
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
jmp 0x2626b
pushq $0x1
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x27064
jmp 0x2670d
movq %rbx, %rdi
callq 0x26edc
movq %rax, %r15
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %r12
movq %r14, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x2699d
movq %r14, %rdi
movq %rbp, %rsi
callq 0x26164
movq (%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x1be9a
movq (%rbx), %rdi
pushq $0x35
popq %rsi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1b718
movq %rax, %rbp
movq (%rbx), %rdi
pushq $0x2
popq %rsi
callq 0x1fdc2
movq %rax, 0x20(%rbp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x26cf2
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
movq %r14, %rdi
movq %r12, %rsi
callq 0x268cb
movq %r14, %rdi
movq %r13, %rsi
callq 0x26164
movq (%rbx), %rdi
xorl %esi, %esi
callq 0x1be9a
movq (%rbx), %rdi
pushq $0x35
popq %rsi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1b718
movq %rax, %r13
movq (%rbx), %rdi
pushq $0x2
popq %rsi
callq 0x1fdc2
movq %rax, 0x20(%r13)
movq %r15, %rdi
movq %r13, %rsi
callq 0x26cf2
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
movq %r14, %rdi
movq %r12, %rsi
callq 0x268cb
jmp 0x2668c
cmpq $0x2, 0x40(%rbx)
jb 0x26739
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x261a7
movq %rax, %rcx
jmp 0x2673b
movq (%r12), %rdi
callq 0x1bf90
movq %rax, %rdi
callq 0x1fcd8
movl (%rax), %eax
andl $-0x2, %eax
cmpl $0x14, %eax
jne 0x263c6
movq (%r12), %r15
movq %rbx, %rdi
callq 0x1bf90
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x26daf
jmp 0x2670d
movq (%r12), %rsi
movq %r14, %rdi
callq 0x261a7
movq %rax, %r14
movq %rbx, %rdi
callq 0x1b5e6
movq 0x8(%r12), %rcx
movq (%rbx), %rdi
movl %eax, %esi
movq %r14, %rdx
jmp 0x26745
movq (%r12), %rsi
movq %r14, %rdi
callq 0x261a7
movq %rax, %r15
movq 0x18(%r14), %rsi
testq %rsi, %rsi
jne 0x26416
movq %r15, %rdi
callq 0x26edc
movq %rax, %rsi
movq %rax, 0x18(%r14)
movq %r14, %rdi
callq 0x26f9c
movq %rax, %rdi
movq %r15, %rsi
callq 0x26cf2
movq %r14, %rdi
movq %rax, %rsi
callq 0x259b0
movq %r14, %rdi
callq 0x26a46
xorl %r15d, %r15d
pushq $0x2
popq %rcx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %r14, %rdi
xorl %esi, %esi
callq 0x26795
testl %eax, %eax
je 0x26727
movq 0x18(%r14), %rdx
movq (%rbx), %rdi
xorl %r15d, %r15d
pushq $0x2f
popq %rsi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1b718
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
jmp 0x26727
cmpl $0x0, 0x48(%r14)
je 0x2677b
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
xorl %r15d, %r15d
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x26795
testl %eax, %eax
je 0x26727
movq 0x30(%r14), %rsi
jmp 0x2658e
movq (%r12), %rsi
movq %r14, %rdi
callq 0x26f9c
movq %rax, %r15
movq %rax, %rdi
callq 0x2701d
jmp 0x264fb
movq (%r12), %rsi
movq %r14, %rdi
callq 0x26f9c
movq %rax, %r15
movq %rax, %rdi
callq 0x26d68
jmp 0x265b2
movq (%r12), %rsi
movq %r14, %rdi
callq 0x26f9c
movq %rax, %r15
movq %rax, %rdi
callq 0x26d68
movq %r15, %rdi
movq %rax, %rsi
callq 0x26cf2
leaq 0x20(%r14), %rdi
addq $0x28, %r14
movq %r14, %rsi
movq %rax, %rdx
jmp 0x26545
movq %rbx, %rdi
callq 0x26edc
movq %rax, %r12
movq 0x50(%rbx), %rax
movq (%rax), %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x26f11
movq %rax, %r15
movq 0x50(%r14), %rsi
leaq 0x50(%rsi), %rdi
addq $0x58, %rsi
movq %r12, %rdx
callq 0x29b2d
jmp 0x26710
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %r14, %rdi
callq 0x26f11
jmp 0x2670d
cmpl $0x0, 0x48(%r14)
je 0x26784
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
pushq $0x1
popq %rcx
movq %r14, %rdi
callq 0x26795
testl %eax, %eax
je 0x26724
movq 0x38(%r14), %rsi
movq %r14, %rdi
callq 0x268cb
jmp 0x26724
movq (%r12), %rsi
movq %r14, %rdi
callq 0x26f9c
movq %rax, %r15
movq %rax, %rdi
callq 0x2701d
movq %r15, %rdi
movq %rax, %rsi
callq 0x26cf2
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
movq %r14, %rdi
movq %r15, %rsi
callq 0x261a7
jmp 0x2670d
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1bc4f
movq %rax, %r12
movq %rbx, %rdi
callq 0x26edc
movq %rax, %r15
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x2699d
movq %r14, %rdi
movq %rbp, %rsi
callq 0x26164
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x261a7
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x26f11
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
movq %r14, %rdi
movq %r12, %rsi
callq 0x268cb
movq %r14, %rdi
movq %r13, %rsi
callq 0x26164
movq 0x50(%rbx), %rax
movq 0x10(%rax), %rsi
movq %r14, %rdi
callq 0x261a7
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x26f11
movq %r14, %rdi
movq %rax, %rsi
callq 0x26164
movq %r14, %rdi
movq %r12, %rsi
callq 0x26164
jmp 0x26710
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x261a7
movq %rax, %r15
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x261a7
movq (%rbx), %rdi
pushq $0x28
popq %rsi
movq %r15, %rdx
movq %rax, %rcx
jmp 0x26745
movq (%r12), %rax
cmpl $0x8, 0x18(%rax)
movq %rbx, %r15
jb 0x26715
jmp 0x26724
movq %rbx, %rdi
callq 0x1bf90
movq %rax, %rdi
callq 0x204b9
testl %eax, %eax
je 0x26702
movq %rbx, %rdi
callq 0x1b5e6
leal -0x2(%rax), %ecx
cmpl $0x3, %ecx
ja 0x26702
addl $0x4d, %eax
movl %eax, 0x18(%rbx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2729d
movq %rax, %r15
testq %r15, %r15
je 0x26724
movq 0x48(%rbx), %rax
testq %rax, %rax
je 0x26727
movq %rax, 0x48(%r15)
jmp 0x26727
xorl %r15d, %r15d
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
pushq $0x36
popq %rsi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1b718
movq %rax, %r15
movq 0x20(%rbx), %rax
movq %rax, 0x20(%r15)
jmp 0x26715
leaq 0xe33a(%rip), %rdi      # 0x34a9d
leaq 0xe2af(%rip), %rsi      # 0x34a19
leaq 0xe348(%rip), %rcx      # 0x34ab9
movl $0x23d, %edx            # imm = 0x23D
callq 0x4180
leaq 0xe379(%rip), %rsi      # 0x34afb
jmp 0x2678b
leaq 0xe34f(%rip), %rsi      # 0x34ada
movq %rbx, %rdi
xorl %eax, %eax
callq 0x120fd