// File: /workspace/github_c_makefile_star2_O2/michaelforney[P]cproc/stmt.c
// Function: stmt
void
stmt(struct func *f, struct scope *s)
{
	char *name;
	struct expr *e;
	struct type *t;
	struct value *v;
	struct block *b[4];
	struct switchcases swtch;

	attr(NULL, 0);
	switch (tok.kind) {
	/* 6.8.2 Compound statement */
	case TLBRACE:
		next();
		s = mkscope(s);
		while (tok.kind != TRBRACE) {
			if (!label(f, s) && !decl(s, f))
				stmt(f, s);
		}
		s = delscope(s);
		next();
		break;

	/* 6.8.3 Expression statement */
	case TSEMICOLON:
		next();
		break;
	default:
		e = expr(s);
		v = funcexpr(f, e);
		delexpr(e);
		expect(TSEMICOLON, "after expression statement");
		break;

	/* 6.8.4 Selection statement */
	case TIF:
		next();
		s = mkscope(s);
		expect(TLPAREN, "after 'if'");
		e = expr(s);
		t = e->type;
		if (!(t->prop & PROPSCALAR))
			error(&tok.loc, "controlling expression of if statement must have scalar type");
		v = funcexpr(f, e);
		delexpr(e);
		expect(TRPAREN, "after expression");

		b[0] = mkblock("if_true");
		b[1] = mkblock("if_false");
		funcjnz(f, v, t, b[0], b[1]);

		funclabel(f, b[0]);
		s = mkscope(s);
		labelstmt(f, s);
		s = delscope(s);

		if (consume(TELSE)) {
			b[2] = mkblock("if_join");
			funcjmp(f, b[2]);
			funclabel(f, b[1]);
			s = mkscope(s);
			labelstmt(f, s);
			s = delscope(s);
			funclabel(f, b[2]);
		} else {
			funclabel(f, b[1]);
		}
		s = delscope(s);
		break;
	case TSWITCH:
		next();

		s = mkscope(s);
		expect(TLPAREN, "after 'switch'");
		e = expr(s);
		expect(TRPAREN, "after expression");

		if (!(e->type->prop & PROPINT))
			error(&tok.loc, "controlling expression of switch statement must have integer type");
		e = exprpromote(e);

		swtch.root = NULL;
		swtch.type = e->type;
		swtch.defaultlabel = NULL;

		b[0] = mkblock("switch_cond");
		b[1] = mkblock("switch_join");

		v = funcexpr(f, e);
		funcjmp(f, b[0]);
		s = mkscope(s);
		s->breaklabel = b[1];
		s->switchcases = &swtch;
		labelstmt(f, s);
		funcjmp(f, b[1]);

		funclabel(f, b[0]);
		funcswitch(f, v, &swtch, swtch.defaultlabel ? swtch.defaultlabel : b[1]);
		s = delscope(s);

		funclabel(f, b[1]);
		s = delscope(s);
		break;

	/* 6.8.5 Iteration statements */
	case TWHILE:
		next();
		s = mkscope(s);
		expect(TLPAREN, "after 'while'");
		e = expr(s);
		t = e->type;
		if (!(t->prop & PROPSCALAR))
			error(&tok.loc, "controlling expression of loop must have scalar type");
		expect(TRPAREN, "after expression");

		b[0] = mkblock("while_cond");
		b[1] = mkblock("while_body");
		b[2] = mkblock("while_join");

		funclabel(f, b[0]);
		v = funcexpr(f, e);
		funcjnz(f, v, t, b[1], b[2]);
		funclabel(f, b[1]);
		s = mkscope(s);
		s->continuelabel = b[0];
		s->breaklabel = b[2];
		labelstmt(f, s);
		s = delscope(s);
		funcjmp(f, b[0]);
		funclabel(f, b[2]);
		s = delscope(s);
		break;
	case TDO:
		next();

		b[0] = mkblock("do_body");
		b[1] = mkblock("do_cond");
		b[2] = mkblock("do_join");

		s = mkscope(s);
		s = mkscope(s);
		s->continuelabel = b[1];
		s->breaklabel = b[2];
		funclabel(f, b[0]);
		labelstmt(f, s);
		s = delscope(s);

		expect(TWHILE, "after 'do' statement");
		expect(TLPAREN, "after 'while'");
		funclabel(f, b[1]);
		e = expr(s);
		t = e->type;
		if (!(t->prop & PROPSCALAR))
			error(&tok.loc, "controlling expression of loop must have scalar type");
		expect(TRPAREN, "after expression");

		v = funcexpr(f, e);
		funcjnz(f, v, t, b[0], b[2]);
		funclabel(f, b[2]);
		s = delscope(s);
		expect(TSEMICOLON, "after 'do' statement");
		break;
	case TFOR:
		next();
		expect(TLPAREN, "after while");
		s = mkscope(s);
		if (!decl(s, f)) {
			if (tok.kind != TSEMICOLON) {
				e = expr(s);
				funcexpr(f, e);
				delexpr(e);
			}
			expect(TSEMICOLON, NULL);
		}

		b[0] = mkblock("for_cond");
		b[1] = mkblock("for_body");
		b[2] = mkblock("for_cont");
		b[3] = mkblock("for_join");

		funclabel(f, b[0]);
		if (tok.kind != TSEMICOLON) {
			e = expr(s);
			t = e->type;
			if (!(t->prop & PROPSCALAR))
				error(&tok.loc, "controlling expression of loop must have scalar type");
			v = funcexpr(f, e);
			funcjnz(f, v, t, b[1], b[3]);
			delexpr(e);
		}
		expect(TSEMICOLON, NULL);
		e = tok.kind == TRPAREN ? NULL : expr(s);
		expect(TRPAREN, NULL);

		funclabel(f, b[1]);
		s = mkscope(s);
		s->breaklabel = b[3];
		s->continuelabel = b[2];
		labelstmt(f, s);
		s = delscope(s);

		funclabel(f, b[2]);
		if (e) {
			funcexpr(f, e);
			delexpr(e);
		}
		funcjmp(f, b[0]);
		funclabel(f, b[3]);
		s = delscope(s);
		break;

	/* 6.8.6 Jump statements */
	case TGOTO:
		next();
		name = expect(TIDENT, "after 'goto'");
		funcjmp(f, funcgoto(f, name)->label);
		expect(TSEMICOLON, "after 'goto' statement");
		break;
	case TCONTINUE:
		next();
		if (!s->continuelabel)
			error(&tok.loc, "'continue' statement must be in loop");
		funcjmp(f, s->continuelabel);
		expect(TSEMICOLON, "after 'continue' statement");
		break;
	case TBREAK:
		next();
		if (!s->breaklabel)
			error(&tok.loc, "'break' statement must be in loop or switch");
		funcjmp(f, s->breaklabel);
		expect(TSEMICOLON, "after 'break' statement");
		break;
	case TRETURN:
		next();
		t = functype(f);
		if (t->base != &typevoid) {
			e = exprassign(expr(s), t->base);
			v = funcexpr(f, e);
			delexpr(e);
		} else {
			v = NULL;
		}
		funcret(f, v);
		expect(TSEMICOLON, "after 'return' statement");
		break;

	case T__ASM__:
		error(&tok.loc, "inline assembly is not yet supported");
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rsi, %r15
movq %rdi, %rbx
xorl %edi, %edi
xorl %esi, %esi
callq 0x334c
leaq 0x10874(%rip), %r14     # 0x1c108
movl (%r14), %eax
leal -0x11(%rax), %ecx
cmpl $0xb, %ecx
jbe 0xb927
cmpl $0xc, %eax
je 0xc094
cmpl $0x23, %eax
je 0xbed8
cmpl $0x2a, %eax
je 0xbf4e
cmpl $0x34, %eax
je 0xbdc0
cmpl $0x3e, %eax
je 0xbf2b
cmpl $0x61, %eax
je 0xc081
cmpl $0x44, %eax
jne 0xb972
callq 0x9c1e
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
cmpl $0x45, (%r14)
je 0xc079
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc0f7
testb %al, %al
jne 0xb8f2
movq %r15, %rdi
movq %rbx, %rsi
callq 0x48e9
testb %al, %al
jne 0xb8f2
movq %rbx, %rdi
movq %r15, %rsi
callq 0xb870
jmp 0xb8f2
leaq 0x863e(%rip), %rax      # 0x13f6c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
callq 0x9c1e
movq 0x48(%r15), %rsi
testq %rsi, %rsi
jne 0xb95e
addq $0x8, %r14
leaq 0x8816(%rip), %rsi      # 0x14166
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
movq 0x48(%r15), %rsi
movq %rbx, %rdi
callq 0xdbe4
leaq 0x881e(%rip), %rsi      # 0x1418b
jmp 0xc0e1
movq %r15, %rdi
callq 0x6e32
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0xdfc5
movq %r14, %rdi
callq 0x63c4
leaq 0x8605(%rip), %rsi      # 0x13f9c
jmp 0xc0e1
callq 0x9c1e
leaq 0x879a(%rip), %rsi      # 0x14142
pushq $0x4
popq %rdi
callq 0xa26e
movq %rbx, %rdi
movq %rax, %rsi
callq 0xdf5b
movq (%rax), %rsi
movq %rbx, %rdi
callq 0xdbe4
leaq 0x8782(%rip), %rsi      # 0x1414f
jmp 0xc0e1
callq 0x9c1e
leaq 0x8707(%rip), %rdi      # 0x140e5
callq 0xd279
movq %rax, %r12
leaq 0x8700(%rip), %rdi      # 0x140ed
callq 0xd279
movq %rax, %rbp
leaq 0x86f9(%rip), %rdi      # 0x140f5
callq 0xd279
movq %rax, %r13
movq %r15, %rdi
callq 0xb6ed
movq %rax, %rdi
callq 0xb6ed
movq %rax, %r15
movq %rbp, 0x48(%rax)
movq %r13, 0x40(%rax)
movq %rbx, %rdi
movq %r12, 0x8(%rsp)
movq %r12, %rsi
callq 0xdb62
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc247
movq %r15, %rdi
callq 0xb718
movq %rax, %r15
leaq 0x86b1(%rip), %rsi      # 0x140fd
pushq $0x34
popq %rdi
callq 0xa26e
leaq 0x8626(%rip), %rsi      # 0x14081
pushq $0x42
popq %rdi
callq 0xa26e
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdb62
movq %r15, %rdi
callq 0x6e32
movq %rax, %r12
movq 0x8(%rax), %rbp
testb $0x10, 0x4(%rbp)
jne 0xba98
addq $0x8, %r14
leaq 0x8601(%rip), %rsi      # 0x1408f
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
leaq 0x702b(%rip), %rsi      # 0x12aca
pushq $0x43
popq %rdi
callq 0xa26e
movq %rbx, %rdi
movq %r12, %rsi
callq 0xdfc5
movq %rbx, %rdi
movq %rax, %rsi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xdbfb
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdb62
movq %r15, %rdi
callq 0xb718
leaq 0x861b(%rip), %rsi      # 0x140fd
jmp 0xc0e1
callq 0x9c1e
leaq 0x861f(%rip), %rsi      # 0x14112
pushq $0x42
popq %rdi
callq 0xa26e
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x48e9
testb %al, %al
jne 0xbb43
cmpl $0x61, (%r14)
je 0xbb39
movq %r15, %rdi
callq 0x6e32
movq %rax, %r12
movq %rbx, %rdi
movq %rax, %rsi
callq 0xdfc5
movq %r12, %rdi
callq 0x63c4
pushq $0x61
popq %rdi
xorl %esi, %esi
callq 0xa26e
leaq 0x85d4(%rip), %rdi      # 0x1411e
callq 0xd279
movq %rax, %rbp
leaq 0x85ce(%rip), %rdi      # 0x14127
callq 0xd279
movq %rax, 0x8(%rsp)
leaq 0x85c6(%rip), %rdi      # 0x14130
callq 0xd279
movq %rax, 0x18(%rsp)
leaq 0x85be(%rip), %rdi      # 0x14139
callq 0xd279
movq %rax, %r13
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdb62
cmpl $0x61, (%r14)
je 0xbbee
movq %rbp, 0x10(%rsp)
movq %r15, %rdi
callq 0x6e32
movq %rax, %r12
movq 0x8(%rax), %rbp
testb $0x10, 0x4(%rbp)
jne 0xbbc0
leaq 0x8(%r14), %rdi
leaq 0x84d6(%rip), %rsi      # 0x1408f
xorl %eax, %eax
callq 0xc536
movq %rbx, %rdi
movq %r12, %rsi
callq 0xdfc5
movq %rbx, %rdi
movq %rax, %rsi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xdbfb
movq %r12, %rdi
callq 0x63c4
movq 0x10(%rsp), %rbp
xorl %r12d, %r12d
pushq $0x61
popq %rdi
xorl %esi, %esi
callq 0xa26e
cmpl $0x43, (%r14)
je 0xbc0c
movq %r15, %rdi
callq 0x6e32
movq %rax, %r12
pushq $0x43
popq %rdi
xorl %esi, %esi
callq 0xa26e
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0xdb62
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r14
movq %r13, 0x40(%rax)
movq 0x18(%rsp), %r15
movq %r15, 0x48(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0xc247
movq %r14, %rdi
callq 0xb718
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdb62
testq %r12, %r12
je 0xbc74
movq %rbx, %rdi
movq %r12, %rsi
callq 0xdfc5
movq %r12, %rdi
callq 0x63c4
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdbe4
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdb62
movq %r14, %rdi
jmp 0xbec5
callq 0x9c1e
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
leaq 0x830e(%rip), %rsi      # 0x13fb7
pushq $0x42
popq %rdi
callq 0xa26e
movq %r15, %rdi
callq 0x6e32
movq %rax, %r13
movq 0x8(%rax), %r12
testb $0x10, 0x4(%r12)
jne 0xbcdd
addq $0x8, %r14
leaq 0x82ef(%rip), %rsi      # 0x13fc2
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdfc5
movq %rax, %rbp
movq %r13, %rdi
callq 0x63c4
leaq 0x6dd0(%rip), %rsi      # 0x12aca
pushq $0x43
popq %rdi
callq 0xa26e
leaq 0x82f6(%rip), %rdi      # 0x13fff
callq 0xd279
movq %rax, %r13
leaq 0x82ef(%rip), %rdi      # 0x14007
callq 0xd279
movq %rax, %r14
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %r13, %rcx
movq %rax, %r8
callq 0xdbfb
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdb62
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xc247
movq %r15, %rdi
callq 0xb718
movq %rax, %r15
pushq $0x15
popq %rdi
callq 0xa28d
testb %al, %al
je 0xbdb5
leaq 0x829d(%rip), %rdi      # 0x14010
callq 0xd279
movq %rax, %r12
movq %rbx, %rdi
movq %rax, %rsi
callq 0xdbe4
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdb62
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0xc247
movq %r14, %rdi
callq 0xb718
movq %rax, %r15
movq %r12, %r14
movq %rbx, %rdi
movq %r14, %rsi
jmp 0xbebd
callq 0x9c1e
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
leaq 0x82aa(%rip), %rsi      # 0x14081
pushq $0x42
popq %rdi
callq 0xa26e
movq %r15, 0x8(%rsp)
movq %r15, %rdi
callq 0x6e32
movq %rax, %r13
movq 0x8(%rax), %r12
testb $0x10, 0x4(%r12)
jne 0xbe10
addq $0x8, %r14
leaq 0x8289(%rip), %rsi      # 0x1408f
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
leaq 0x6cb3(%rip), %rsi      # 0x12aca
pushq $0x43
popq %rdi
callq 0xa26e
leaq 0x829e(%rip), %rdi      # 0x140c4
callq 0xd279
movq %rax, %r14
leaq 0x829a(%rip), %rdi      # 0x140cf
callq 0xd279
movq %rax, %r15
leaq 0x8296(%rip), %rdi      # 0x140da
callq 0xd279
movq %rax, %rbp
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdb62
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdfc5
movq %rbx, %rdi
movq %rax, %rsi
movq %r12, %rdx
movq %r15, %rcx
movq %rbp, %r8
callq 0xdbfb
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdb62
movq 0x8(%rsp), %rdi
callq 0xb6ed
movq %rax, %r15
movq %r14, 0x48(%rax)
movq %rbp, 0x40(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0xc247
movq %r15, %rdi
callq 0xb718
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdbe4
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdb62
movq %r15, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb718
callq 0x9c1e
movq %rbx, %rdi
callq 0xdbdf
movq %rax, %r14
movq 0x20(%rax), %rax
cmpq 0xf0ad(%rip), %rax      # 0x1afa0
je 0xc0cc
movq %r15, %rdi
callq 0x6e32
movq 0x20(%r14), %rsi
movq %rax, %rdi
callq 0x6441
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xdfc5
movq %rax, %r14
movq %r15, %rdi
callq 0x63c4
jmp 0xc0cf
addq $0x8, %r14
leaq 0x82cd(%rip), %rsi      # 0x14203
movq %r14, %rdi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xc536
callq 0x9c1e
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
leaq 0x80b3(%rip), %rsi      # 0x14018
pushq $0x42
popq %rdi
callq 0xa26e
movq %r15, %rdi
callq 0x6e32
movq %rax, %r12
leaq 0x6b4b(%rip), %rsi      # 0x12aca
pushq $0x43
popq %rdi
callq 0xa26e
movq 0x8(%r12), %rax
testb $0x2, 0x4(%rax)
jne 0xbfa7
addq $0x8, %r14
leaq 0x808a(%rip), %rsi      # 0x14027
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
movq %r12, %rdi
callq 0x664f
movq %rax, %rbp
leaq 0x20(%rsp), %r14
andq $0x0, (%r14)
movq 0x8(%rax), %rax
movq %rax, 0x8(%r14)
andq $0x0, 0x10(%r14)
leaq 0x809a(%rip), %rdi      # 0x14069
callq 0xd279
movq %rax, %r13
leaq 0x8097(%rip), %rdi      # 0x14075
callq 0xd279
movq %rax, %r12
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xdfc5
movq %rax, %rbp
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdbe4
movq %r15, %rdi
callq 0xb6ed
movq %rax, %r15
movq %r12, 0x40(%rax)
movq %r14, 0x50(%rax)
movq %rbx, %rdi
movq %rax, %rsi
callq 0xc247
movq %rbx, %rdi
movq %r12, %rsi
callq 0xdbe4
movq %rbx, %rdi
movq %r13, %rsi
callq 0xdb62
movq 0x10(%r14), %rcx
testq %rcx, %rcx
cmoveq %r12, %rcx
movq %rbx, %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0xf1e2
movq %r15, %rdi
callq 0xb718
movq %rax, %r14
movq %rbx, %rdi
movq %r12, %rsi
callq 0xdb62
movq %r14, %rdi
callq 0xb718
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, %rdi
callq 0xb718
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9c1e
callq 0x9c1e
movq 0x40(%r15), %rsi
testq %rsi, %rsi
jne 0xc0bb
addq $0x8, %r14
leaq 0x80f9(%rip), %rsi      # 0x141a6
movq %r14, %rdi
xorl %eax, %eax
callq 0xc536
movq 0x40(%r15), %rsi
movq %rbx, %rdi
callq 0xdbe4
leaq 0x8108(%rip), %rsi      # 0x141d2
jmp 0xc0e1
xorl %r14d, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xdf31
leaq 0x8109(%rip), %rsi      # 0x141ea
pushq $0x61
popq %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa26e