// File: /workspace/github_c_makefile_star2_O1/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 0x33ec
leaq 0xf8d0(%rip), %r14      # 0x1c108
movl (%r14), %eax
cmpl $0x22, %eax
jg 0xc895
leal -0x11(%rax), %ecx
cmpl $0xb, %ecx
ja 0xca35
leaq 0x86b9(%rip), %rax      # 0x14f0c
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
callq 0xa9d0
cmpq $0x0, 0x48(%r15)
jne 0xc87d
addq $0x8, %r14
leaq 0x8893(%rip), %rsi      # 0x15106
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
movq 0x48(%r15), %rsi
movq %rbx, %rdi
callq 0xedd4
leaq 0x889b(%rip), %rsi      # 0x1512b
jmp 0xd11c
cmpl $0x3d, %eax
jg 0xc9d5
cmpl $0x23, %eax
je 0xcf29
cmpl $0x2a, %eax
je 0xcf9f
cmpl $0x34, %eax
jne 0xca73
callq 0xa9d0
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
leaq 0x8751(%rip), %rsi      # 0x15021
movl $0x42, %edi
callq 0xb07a
movq %r15, 0x8(%rsp)
movq %r15, %rdi
callq 0x73a2
movq %rax, %rbp
movq 0x8(%rax), %r13
testb $0x10, 0x4(%r13)
jne 0xc90a
addq $0x8, %r14
leaq 0x872f(%rip), %rsi      # 0x1502f
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
leaq 0x7159(%rip), %rsi      # 0x13a6a
movl $0x43, %edi
callq 0xb07a
leaq 0x8742(%rip), %rdi      # 0x15064
callq 0xe2e3
movq %rax, %r14
leaq 0x873e(%rip), %rdi      # 0x1506f
callq 0xe2e3
movq %rax, %r15
leaq 0x873a(%rip), %rdi      # 0x1507a
callq 0xe2e3
movq %rax, %r12
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed47
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf240
movq %rbx, %rdi
movq %rax, %rsi
movq %r13, %rdx
movq %r15, %rcx
movq %r12, %r8
callq 0xedeb
movq %rbx, %rdi
movq %r15, %rsi
callq 0xed47
movq 0x8(%rsp), %rdi
callq 0xc684
movq %rax, %r15
movq %r14, 0x48(%rax)
movq %r12, 0x40(%rax)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd134
testb %al, %al
jne 0xc992
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc814
movq %r15, %rdi
callq 0xc6b9
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xedd4
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed47
movq %r15, %rdi
jmp 0xd0f4
cmpl $0x3e, %eax
je 0xcf7c
cmpl $0x61, %eax
je 0xcf16
cmpl $0x44, %eax
jne 0xca73
callq 0xa9d0
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
cmpl $0x45, (%r14)
je 0xcf0e
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd134
testb %al, %al
jne 0xca00
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4c95
testb %al, %al
jne 0xca00
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc814
jmp 0xca00
cmpl $0xc, %eax
jne 0xca73
callq 0xa9d0
cmpq $0x0, 0x40(%r15)
jne 0xca5b
addq $0x8, %r14
leaq 0x86f5(%rip), %rsi      # 0x15146
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
movq 0x40(%r15), %rsi
movq %rbx, %rdi
callq 0xedd4
leaq 0x8704(%rip), %rsi      # 0x15172
jmp 0xd11c
movq %r15, %rdi
callq 0x73a2
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf240
movq %r14, %rdi
callq 0x689c
leaq 0x84a4(%rip), %rsi      # 0x14f3c
jmp 0xd11c
callq 0xa9d0
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
leaq 0x84a3(%rip), %rsi      # 0x14f57
movl $0x42, %edi
callq 0xb07a
movq %r15, %rdi
callq 0x73a2
movq %rax, %r13
movq 0x8(%rax), %r12
testb $0x10, 0x4(%r12)
jne 0xcaea
addq $0x8, %r14
leaq 0x8482(%rip), %rsi      # 0x14f62
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
movq %rbx, %rdi
movq %r13, %rsi
callq 0xf240
movq %rax, %rbp
movq %r13, %rdi
callq 0x689c
leaq 0x6f63(%rip), %rsi      # 0x13a6a
movl $0x43, %edi
callq 0xb07a
leaq 0x8487(%rip), %rdi      # 0x14f9f
callq 0xe2e3
movq %rax, %r13
leaq 0x8480(%rip), %rdi      # 0x14fa7
callq 0xe2e3
movq %rax, %r14
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %r13, %rcx
movq %rax, %r8
callq 0xedeb
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed47
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd134
testb %al, %al
jne 0xcb59
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc814
movq %r15, %rdi
callq 0xc6b9
movq %rax, %r12
movl $0x15, %edi
callq 0xb099
testb %al, %al
je 0xd0e3
leaq 0x8419(%rip), %rdi      # 0x14fb0
callq 0xe2e3
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xedd4
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed47
movq %r12, %rdi
callq 0xc684
movq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0xd134
testb %al, %al
jne 0xcbc0
movq %rbx, %rdi
movq %r14, %rsi
callq 0xc814
movq %r14, %rdi
callq 0xc6b9
movq %rax, %r12
jmp 0xd0e6
callq 0xa9d0
leaq 0x84ec(%rip), %rsi      # 0x150e2
movl $0x4, %edi
callq 0xb07a
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf19d
movq (%rax), %rsi
movq %rbx, %rdi
callq 0xedd4
leaq 0x84d2(%rip), %rsi      # 0x150ef
jmp 0xd11c
callq 0xa9d0
leaq 0x8457(%rip), %rdi      # 0x15085
callq 0xe2e3
movq %rax, %r12
leaq 0x8450(%rip), %rdi      # 0x1508d
callq 0xe2e3
movq %rax, %rbp
leaq 0x8449(%rip), %rdi      # 0x15095
callq 0xe2e3
movq %rax, %r13
movq %r15, %rdi
callq 0xc684
movq %rax, %rdi
callq 0xc684
movq %rax, %r15
movq %rbp, 0x48(%rax)
movq %r13, 0x40(%rax)
movq %rbx, %rdi
movq %r12, 0x8(%rsp)
movq %r12, %rsi
callq 0xed47
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd134
testb %al, %al
jne 0xcc7f
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc814
movq %r15, %rdi
callq 0xc6b9
movq %rax, %r15
leaq 0x83f2(%rip), %rsi      # 0x1509d
movl $0x34, %edi
callq 0xb07a
leaq 0x8365(%rip), %rsi      # 0x15021
movl $0x42, %edi
callq 0xb07a
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xed47
movq %r15, %rdi
callq 0x73a2
movq %rax, %r12
movq 0x8(%rax), %rbp
testb $0x10, 0x4(%rbp)
jne 0xccfb
addq $0x8, %r14
leaq 0x833e(%rip), %rsi      # 0x1502f
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
leaq 0x6d68(%rip), %rsi      # 0x13a6a
movl $0x43, %edi
callq 0xb07a
movq %rbx, %rdi
movq %r12, %rsi
callq 0xf240
movq %rbx, %rdi
movq %rax, %rsi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xedeb
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed47
movq %r15, %rdi
callq 0xc6b9
leaq 0x8356(%rip), %rsi      # 0x1509d
jmp 0xd11c
callq 0xa9d0
leaq 0x835a(%rip), %rsi      # 0x150b2
movl $0x42, %edi
callq 0xb07a
movq %r15, %rdi
callq 0xc684
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4c95
testb %al, %al
jne 0xcdac
cmpl $0x61, (%r14)
je 0xcda0
movq %r12, %rdi
callq 0x73a2
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf240
movq %r15, %rdi
callq 0x689c
movl $0x61, %edi
xorl %esi, %esi
callq 0xb07a
leaq 0x830b(%rip), %rdi      # 0x150be
callq 0xe2e3
movq %rax, %r15
leaq 0x8305(%rip), %rdi      # 0x150c7
callq 0xe2e3
movq %rax, 0x8(%rsp)
leaq 0x82fd(%rip), %rdi      # 0x150d0
callq 0xe2e3
movq %rax, 0x18(%rsp)
leaq 0x82f5(%rip), %rdi      # 0x150d9
callq 0xe2e3
movq %rax, %r13
movq %rbx, %rdi
movq %r15, %rsi
callq 0xed47
cmpl $0x61, (%r14)
je 0xce58
movq %r15, 0x10(%rsp)
movq %r12, %rdi
callq 0x73a2
movq %rax, %rbp
movq 0x8(%rax), %r15
testb $0x10, 0x4(%r15)
jne 0xce2a
leaq 0x8(%r14), %rdi
leaq 0x820c(%rip), %rsi      # 0x1502f
xorl %eax, %eax
callq 0xd56a
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf240
movq %rbx, %rdi
movq %rax, %rsi
movq %r15, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xedeb
movq %rbp, %rdi
callq 0x689c
movq 0x10(%rsp), %r15
xorl %ebp, %ebp
movl $0x61, %edi
xorl %esi, %esi
callq 0xb07a
cmpl $0x43, (%r14)
je 0xce77
movq %r12, %rdi
callq 0x73a2
movq %rax, %rbp
movl $0x43, %edi
xorl %esi, %esi
callq 0xb07a
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0xed47
movq %r12, %rdi
callq 0xc684
movq %rax, %r14
movq %r13, 0x40(%rax)
movq 0x18(%rsp), %r12
movq %r12, 0x48(%rax)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xd134
testb %al, %al
jne 0xcea8
movq %rbx, %rdi
movq %r14, %rsi
callq 0xc814
movq %r14, %rdi
callq 0xc6b9
movq %rax, %r14
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed47
testq %rbp, %rbp
je 0xcef0
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf240
movq %rbp, %rdi
callq 0x689c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xedd4
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed47
movq %r14, %rdi
jmp 0xd0f4
movq %r15, %rdi
callq 0xc6b9
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa9d0
callq 0xa9d0
movq %rbx, %rdi
callq 0xedcf
movq %rax, %r14
movq 0x20(%rax), %rax
cmpq 0xe05c(%rip), %rax      # 0x1afa0
je 0xd107
movq %r15, %rdi
callq 0x73a2
movq 0x20(%r14), %rsi
movq %rax, %rdi
callq 0x691c
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf240
movq %rax, %r14
movq %r15, %rdi
callq 0x689c
jmp 0xd10a
addq $0x8, %r14
leaq 0x821c(%rip), %rsi      # 0x151a3
movq %r14, %rdi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xd56a
callq 0xa9d0
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
leaq 0x8002(%rip), %rsi      # 0x14fb8
movl $0x42, %edi
callq 0xb07a
movq %r15, %rdi
callq 0x73a2
movq %rax, %r12
leaq 0x6a98(%rip), %rsi      # 0x13a6a
movl $0x43, %edi
callq 0xb07a
movq 0x8(%r12), %rax
testb $0x2, 0x4(%rax)
jne 0xcffc
addq $0x8, %r14
leaq 0x7fd5(%rip), %rsi      # 0x14fc7
movq %r14, %rdi
xorl %eax, %eax
callq 0xd56a
movq %r12, %rdi
callq 0x6b42
movq %rax, %r13
xorl %eax, %eax
leaq 0x20(%rsp), %rbp
movq %rax, (%rbp)
movq 0x8(%r13), %rcx
movq %rcx, 0x8(%rbp)
movq %rax, 0x10(%rbp)
leaq 0x7fe4(%rip), %rdi      # 0x15009
callq 0xe2e3
movq %rax, %r12
leaq 0x7fe1(%rip), %rdi      # 0x15015
callq 0xe2e3
movq %rax, %r14
movq %rbx, %rdi
movq %r13, %rsi
callq 0xf240
movq %rax, %r13
movq %rbx, %rdi
movq %r12, %rsi
callq 0xedd4
movq %r15, %rdi
callq 0xc684
movq %rax, %r15
movq %r14, 0x40(%rax)
movq %rbp, 0x50(%rax)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd134
testb %al, %al
jne 0xd068
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc814
movq %rbx, %rdi
movq %r14, %rsi
callq 0xedd4
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed47
leaq 0x20(%rsp), %rdx
movq 0x10(%rdx), %rax
testq %rax, %rax
movq %r14, %rcx
cmovneq %rax, %rcx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1075b
movq %r15, %rdi
callq 0xc6b9
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed47
movq %r15, %rdi
callq 0xc6b9
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xed47
movq %r12, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xc6b9
xorl %r14d, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xf173
leaq 0x806e(%rip), %rsi      # 0x1518a
movl $0x61, %edi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb07a