// File: /workspace/github_c_makefile_star2_O3/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 0x1d422
decl %eax
cmpl $0x39, %eax
ja 0x297a0
leaq 0xf006(%rip), %rcx      # 0x38290
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
movq %rbx, %r15
jmpq *%rax
movq %rbx, %rdi
callq 0x1d422
movl %eax, %eax
leaq 0xf119(%rip), %r13      # 0x383c0
cmpl $0x0, (%r13,%rax,4)
je 0x29826
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %r15
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x2925b
movq %rax, %r14
movq %rbx, %rdi
callq 0x1d422
movl %eax, %eax
movl (%r13,%rax,4), %esi
movq (%rbx), %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1d5e2
movq 0x20(%r15), %rcx
movq %rcx, 0x20(%rax)
movq %r15, %rdi
movq %rax, %rsi
callq 0x29de7
jmp 0x297d5
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
jmp 0x29321
movq %r14, %rdi
movq %rbx, %rsi
movl $0x1, %edx
callq 0x2a17c
jmp 0x297d5
movq %rbx, %rdi
callq 0x29fee
movq %rax, %r15
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %r12
movq %r14, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x29a89
movq %r14, %rdi
movq %rbp, %rsi
callq 0x29218
movq (%rbx), %rdi
movl $0x1, %esi
callq 0x1e1c7
movq (%rbx), %rdi
movl $0x35, %esi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d5e2
movq %rax, %rbp
movq (%rbx), %rdi
movl $0x2, %esi
callq 0x2289d
movq %rax, 0x20(%rbp)
movq %r15, %rdi
movq %rbp, %rsi
callq 0x29de7
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
movq %r14, %rdi
movq %r12, %rsi
callq 0x299a5
movq %r14, %rdi
movq %r13, %rsi
callq 0x29218
movq (%rbx), %rdi
xorl %esi, %esi
callq 0x1e1c7
movq (%rbx), %rdi
movl $0x35, %esi
movq %rax, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d5e2
movq %rax, %r13
movq (%rbx), %rdi
movl $0x2, %esi
callq 0x2289d
movq %rax, 0x20(%r13)
movq %r15, %rdi
movq %r13, %rsi
callq 0x29de7
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
movq %r14, %rdi
movq %r12, %rsi
callq 0x299a5
jmp 0x29752
cmpq $0x2, 0x40(%rbx)
jb 0x29801
movq 0x8(%r12), %rsi
movq %r14, %rdi
callq 0x2925b
movq %rax, %rcx
jmp 0x29803
movq (%r12), %rdi
callq 0x1e384
movq %rax, %rdi
callq 0x227ac
movl (%rax), %eax
andl $-0x2, %eax
cmpl $0x14, %eax
jne 0x29486
movq (%r12), %r15
movq %rbx, %rdi
callq 0x1e384
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x29eac
jmp 0x297d5
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2925b
movq %rax, %r14
movq %rbx, %rdi
callq 0x1d422
movq 0x8(%r12), %rcx
movq (%rbx), %rdi
movl %eax, %esi
movq %r14, %rdx
jmp 0x2980f
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2925b
movq %rax, %r15
movq 0x18(%r14), %rsi
testq %rsi, %rsi
jne 0x294d6
movq %r15, %rdi
callq 0x29fee
movq %rax, %rsi
movq %rax, 0x18(%r14)
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %rdi
movq %r15, %rsi
callq 0x29de7
movq %r14, %rdi
movq %rax, %rsi
callq 0x28a49
movq %r14, %rdi
callq 0x29b32
xorl %r15d, %r15d
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %r14, %rdi
xorl %esi, %esi
movl $0x2, %ecx
callq 0x2985f
testl %eax, %eax
je 0x297ef
movq 0x18(%r14), %rdx
movq (%rbx), %rdi
xorl %r15d, %r15d
movl $0x2f, %esi
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x1d5e2
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
jmp 0x297ef
cmpl $0x0, 0x48(%r14)
je 0x29845
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
xorl %r15d, %r15d
movq %r14, %rdi
xorl %ecx, %ecx
callq 0x2985f
testl %eax, %eax
je 0x297ef
movq 0x30(%r14), %rsi
jmp 0x29654
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %r15
movq %rax, %rdi
callq 0x2a131
jmp 0x295bf
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %r15
movq %rax, %rdi
callq 0x29e61
jmp 0x29678
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %r15
movq %rax, %rdi
callq 0x29e61
movq %r15, %rdi
movq %rax, %rsi
callq 0x29de7
leaq 0x20(%r14), %rdi
addq $0x28, %r14
movq %r14, %rsi
movq %rax, %rdx
jmp 0x29609
movq %rbx, %rdi
callq 0x29fee
movq %rax, %r12
movq 0x50(%rbx), %rax
movq (%rax), %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x2a025
movq %rax, %r15
movq 0x50(%r14), %rsi
leaq 0x50(%rsi), %rdi
addq $0x58, %rsi
movq %r12, %rdx
callq 0x2ceff
jmp 0x297d8
movq (%r12), %rsi
movq 0x8(%r12), %rdx
movq %r14, %rdi
callq 0x2a025
jmp 0x297d5
cmpl $0x0, 0x48(%r14)
je 0x2984e
movq 0x40(%r14), %rsi
movq (%rbx), %rdx
movq %r14, %rdi
movl $0x1, %ecx
callq 0x2985f
testl %eax, %eax
je 0x297ec
movq 0x38(%r14), %rsi
movq %r14, %rdi
callq 0x299a5
jmp 0x297ec
movq (%r12), %rsi
movq %r14, %rdi
callq 0x2a0b0
movq %rax, %r15
movq %rax, %rdi
callq 0x2a131
movq %r15, %rdi
movq %rax, %rsi
callq 0x29de7
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
movq %r14, %rdi
movq %r15, %rsi
callq 0x2925b
jmp 0x297d5
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %rbp
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %r13
movq (%rbx), %rdi
callq 0x1de03
movq %rax, %r12
movq %rbx, %rdi
callq 0x29fee
movq %rax, %r15
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
movq %rbp, %rdx
movq %r13, %rcx
callq 0x29a89
movq %r14, %rdi
movq %rbp, %rsi
callq 0x29218
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x2925b
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2a025
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
movq %r14, %rdi
movq %r12, %rsi
callq 0x299a5
movq %r14, %rdi
movq %r13, %rsi
callq 0x29218
movq 0x50(%rbx), %rax
movq 0x10(%rax), %rsi
movq %r14, %rdi
callq 0x2925b
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2a025
movq %r14, %rdi
movq %rax, %rsi
callq 0x29218
movq %r14, %rdi
movq %r12, %rsi
callq 0x29218
jmp 0x297d8
movq 0x50(%rbx), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x2925b
movq %rax, %r15
movq 0x50(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdi
callq 0x2925b
movq (%rbx), %rdi
movl $0x28, %esi
movq %r15, %rdx
movq %rax, %rcx
jmp 0x2980f
movq (%r12), %rax
cmpl $0x8, 0x18(%rax)
movq %rbx, %r15
jb 0x297dd
jmp 0x297ec
movq %rbx, %rdi
callq 0x1e384
movq %rax, %rdi
callq 0x23002
testl %eax, %eax
je 0x297ca
movq %rbx, %rdi
callq 0x1d422
leal -0x2(%rax), %ecx
cmpl $0x3, %ecx
ja 0x297ca
addl $0x4d, %eax
movl %eax, 0x18(%rbx)
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2a3c4
movq %rax, %r15
testq %r15, %r15
je 0x297ec
movq 0x48(%rbx), %rax
testq %rax, %rax
je 0x297ef
movq %rax, 0x48(%r15)
jmp 0x297ef
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
movl $0x36, %esi
xorl %r8d, %r8d
xorl %eax, %eax
callq 0x1d5e2
movq %rax, %r15
movq 0x20(%rbx), %rax
movq %rax, 0x20(%r15)
jmp 0x297dd
leaq 0xf250(%rip), %rdi      # 0x38a7d
leaq 0xf1c5(%rip), %rsi      # 0x389f9
leaq 0xf25e(%rip), %rcx      # 0x38a99
movl $0x23d, %edx            # imm = 0x23D
callq 0x4180
leaq 0xf28f(%rip), %rsi      # 0x38adb
jmp 0x29855
leaq 0xf265(%rip), %rsi      # 0x38aba
movq %rbx, %rdi
xorl %eax, %eax
callq 0x138e7