// File: /workspace/github_c_makefile_star2_O3/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 0xf8bc(%rip), %r14      # 0x1c108
movl (%r14), %eax
cmpl $0x22, %eax
jg 0xc8ab
leal -0x11(%rax), %ecx
cmpl $0xb, %ecx
ja 0xca4b
leaq 0x873d(%rip), %rax      # 0x14fa4
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
callq 0xa920
movq 0x48(%r15), %rsi
testq %rsi, %rsi
jne 0xc897
addq $0x8, %r14
leaq 0x8915(%rip), %rsi      # 0x1519e
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
movq 0x48(%r15), %rsi
movq %rbx, %rdi
callq 0xede1
leaq 0x891d(%rip), %rsi      # 0x151c3
jmp 0xd134
cmpl $0x3d, %eax
jg 0xc9eb
cmpl $0x23, %eax
je 0xcf41
cmpl $0x2a, %eax
je 0xcfb7
cmpl $0x34, %eax
jne 0xca8b
callq 0xa920
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
leaq 0x87d3(%rip), %rsi      # 0x150b9
movl $0x42, %edi
callq 0xafeb
movq %r15, 0x8(%rsp)
movq %r15, %rdi
callq 0x7252
movq %rax, %rbp
movq 0x8(%rax), %r13
testb $0x10, 0x4(%r13)
jne 0xc920
addq $0x8, %r14
leaq 0x87b1(%rip), %rsi      # 0x150c7
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
leaq 0x71a3(%rip), %rsi      # 0x13aca
movl $0x43, %edi
callq 0xafeb
leaq 0x87c4(%rip), %rdi      # 0x150fc
callq 0xe2df
movq %rax, %r14
leaq 0x87c0(%rip), %rdi      # 0x15107
callq 0xe2df
movq %rax, %r15
leaq 0x87bc(%rip), %rdi      # 0x15112
callq 0xe2df
movq %rax, %r12
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed54
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf251
movq %rbx, %rdi
movq %rax, %rsi
movq %r13, %rdx
movq %r15, %rcx
movq %r12, %r8
callq 0xedf8
movq %rbx, %rdi
movq %r15, %rsi
callq 0xed54
movq 0x8(%rsp), %rdi
callq 0xc6a0
movq %rax, %r15
movq %r14, 0x48(%rax)
movq %r12, 0x40(%rax)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd14c
testb %al, %al
jne 0xc9a8
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc828
movq %r15, %rdi
callq 0xc6cd
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xede1
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed54
movq %r15, %rdi
jmp 0xd10c
cmpl $0x3e, %eax
je 0xcf94
cmpl $0x61, %eax
je 0xcf2e
cmpl $0x44, %eax
jne 0xca8b
callq 0xa920
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
cmpl $0x45, (%r14)
je 0xcf26
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd14c
testb %al, %al
jne 0xca16
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4aeb
testb %al, %al
jne 0xca16
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc828
jmp 0xca16
cmpl $0xc, %eax
jne 0xca8b
callq 0xa920
movq 0x40(%r15), %rsi
testq %rsi, %rsi
jne 0xca77
addq $0x8, %r14
leaq 0x8775(%rip), %rsi      # 0x151de
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
movq 0x40(%r15), %rsi
movq %rbx, %rdi
callq 0xede1
leaq 0x8784(%rip), %rsi      # 0x1520a
jmp 0xd134
movq %r15, %rdi
callq 0x7252
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf251
movq %r14, %rdi
callq 0x6710
leaq 0x8524(%rip), %rsi      # 0x14fd4
jmp 0xd134
callq 0xa920
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
leaq 0x8523(%rip), %rsi      # 0x14fef
movl $0x42, %edi
callq 0xafeb
movq %r15, %rdi
callq 0x7252
movq %rax, %r13
movq 0x8(%rax), %r12
testb $0x10, 0x4(%r12)
jne 0xcb02
addq $0x8, %r14
leaq 0x8502(%rip), %rsi      # 0x14ffa
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
movq %rbx, %rdi
movq %r13, %rsi
callq 0xf251
movq %rax, %rbp
movq %r13, %rdi
callq 0x6710
leaq 0x6fab(%rip), %rsi      # 0x13aca
movl $0x43, %edi
callq 0xafeb
leaq 0x8507(%rip), %rdi      # 0x15037
callq 0xe2df
movq %rax, %r13
leaq 0x8500(%rip), %rdi      # 0x1503f
callq 0xe2df
movq %rax, %r14
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %r13, %rcx
movq %rax, %r8
callq 0xedf8
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed54
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd14c
testb %al, %al
jne 0xcb71
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc828
movq %r15, %rdi
callq 0xc6cd
movq %rax, %r12
movl $0x15, %edi
callq 0xb00a
testb %al, %al
je 0xd0fb
leaq 0x8499(%rip), %rdi      # 0x15048
callq 0xe2df
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xede1
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed54
movq %r12, %rdi
callq 0xc6a0
movq %rax, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0xd14c
testb %al, %al
jne 0xcbd8
movq %rbx, %rdi
movq %r14, %rsi
callq 0xc828
movq %r14, %rdi
callq 0xc6cd
movq %rax, %r12
jmp 0xd0fe
callq 0xa920
leaq 0x856c(%rip), %rsi      # 0x1517a
movl $0x4, %edi
callq 0xafeb
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf1ae
movq (%rax), %rsi
movq %rbx, %rdi
callq 0xede1
leaq 0x8552(%rip), %rsi      # 0x15187
jmp 0xd134
callq 0xa920
leaq 0x84d7(%rip), %rdi      # 0x1511d
callq 0xe2df
movq %rax, %r12
leaq 0x84d0(%rip), %rdi      # 0x15125
callq 0xe2df
movq %rax, %rbp
leaq 0x84c9(%rip), %rdi      # 0x1512d
callq 0xe2df
movq %rax, %r13
movq %r15, %rdi
callq 0xc6a0
movq %rax, %rdi
callq 0xc6a0
movq %rax, %r15
movq %rbp, 0x48(%rax)
movq %r13, 0x40(%rax)
movq %rbx, %rdi
movq %r12, 0x8(%rsp)
movq %r12, %rsi
callq 0xed54
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd14c
testb %al, %al
jne 0xcc97
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc828
movq %r15, %rdi
callq 0xc6cd
movq %rax, %r15
leaq 0x8472(%rip), %rsi      # 0x15135
movl $0x34, %edi
callq 0xafeb
leaq 0x83e5(%rip), %rsi      # 0x150b9
movl $0x42, %edi
callq 0xafeb
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xed54
movq %r15, %rdi
callq 0x7252
movq %rax, %r12
movq 0x8(%rax), %rbp
testb $0x10, 0x4(%rbp)
jne 0xcd13
addq $0x8, %r14
leaq 0x83be(%rip), %rsi      # 0x150c7
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
leaq 0x6db0(%rip), %rsi      # 0x13aca
movl $0x43, %edi
callq 0xafeb
movq %rbx, %rdi
movq %r12, %rsi
callq 0xf251
movq %rbx, %rdi
movq %rax, %rsi
movq %rbp, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xedf8
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed54
movq %r15, %rdi
callq 0xc6cd
leaq 0x83d6(%rip), %rsi      # 0x15135
jmp 0xd134
callq 0xa920
leaq 0x83da(%rip), %rsi      # 0x1514a
movl $0x42, %edi
callq 0xafeb
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4aeb
testb %al, %al
jne 0xcdc4
cmpl $0x61, (%r14)
je 0xcdb8
movq %r12, %rdi
callq 0x7252
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf251
movq %r15, %rdi
callq 0x6710
movl $0x61, %edi
xorl %esi, %esi
callq 0xafeb
leaq 0x838b(%rip), %rdi      # 0x15156
callq 0xe2df
movq %rax, %r15
leaq 0x8385(%rip), %rdi      # 0x1515f
callq 0xe2df
movq %rax, 0x8(%rsp)
leaq 0x837d(%rip), %rdi      # 0x15168
callq 0xe2df
movq %rax, 0x18(%rsp)
leaq 0x8375(%rip), %rdi      # 0x15171
callq 0xe2df
movq %rax, %r13
movq %rbx, %rdi
movq %r15, %rsi
callq 0xed54
cmpl $0x61, (%r14)
je 0xce70
movq %r15, 0x10(%rsp)
movq %r12, %rdi
callq 0x7252
movq %rax, %rbp
movq 0x8(%rax), %r15
testb $0x10, 0x4(%r15)
jne 0xce42
leaq 0x8(%r14), %rdi
leaq 0x828c(%rip), %rsi      # 0x150c7
xorl %eax, %eax
callq 0xd55c
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf251
movq %rbx, %rdi
movq %rax, %rsi
movq %r15, %rdx
movq 0x8(%rsp), %rcx
movq %r13, %r8
callq 0xedf8
movq %rbp, %rdi
callq 0x6710
movq 0x10(%rsp), %r15
xorl %ebp, %ebp
movl $0x61, %edi
xorl %esi, %esi
callq 0xafeb
cmpl $0x43, (%r14)
je 0xce8f
movq %r12, %rdi
callq 0x7252
movq %rax, %rbp
movl $0x43, %edi
xorl %esi, %esi
callq 0xafeb
movq %rbx, %rdi
movq 0x8(%rsp), %rsi
callq 0xed54
movq %r12, %rdi
callq 0xc6a0
movq %rax, %r14
movq %r13, 0x40(%rax)
movq 0x18(%rsp), %r12
movq %r12, 0x48(%rax)
movq %rbx, %rdi
movq %r14, %rsi
callq 0xd14c
testb %al, %al
jne 0xcec0
movq %rbx, %rdi
movq %r14, %rsi
callq 0xc828
movq %r14, %rdi
callq 0xc6cd
movq %rax, %r14
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed54
testq %rbp, %rbp
je 0xcf08
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xf251
movq %rbp, %rdi
callq 0x6710
movq %rbx, %rdi
movq %r15, %rsi
callq 0xede1
movq %rbx, %rdi
movq %r13, %rsi
callq 0xed54
movq %r14, %rdi
jmp 0xd10c
movq %r15, %rdi
callq 0xc6cd
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa920
callq 0xa920
movq %rbx, %rdi
callq 0xeddc
movq %rax, %r14
movq 0x20(%rax), %rax
cmpq 0xe044(%rip), %rax      # 0x1afa0
je 0xd11f
movq %r15, %rdi
callq 0x7252
movq 0x20(%r14), %rsi
movq %rax, %rdi
callq 0x6790
movq %rax, %r15
movq %rbx, %rdi
movq %rax, %rsi
callq 0xf251
movq %rax, %r14
movq %r15, %rdi
callq 0x6710
jmp 0xd122
addq $0x8, %r14
leaq 0x829c(%rip), %rsi      # 0x1523b
movq %r14, %rdi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xd55c
callq 0xa920
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
leaq 0x8082(%rip), %rsi      # 0x15050
movl $0x42, %edi
callq 0xafeb
movq %r15, %rdi
callq 0x7252
movq %rax, %r12
leaq 0x6ae0(%rip), %rsi      # 0x13aca
movl $0x43, %edi
callq 0xafeb
movq 0x8(%r12), %rax
testb $0x2, 0x4(%rax)
jne 0xd014
addq $0x8, %r14
leaq 0x8055(%rip), %rsi      # 0x1505f
movq %r14, %rdi
xorl %eax, %eax
callq 0xd55c
movq %r12, %rdi
callq 0x69b6
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 0x8064(%rip), %rdi      # 0x150a1
callq 0xe2df
movq %rax, %r12
leaq 0x8061(%rip), %rdi      # 0x150ad
callq 0xe2df
movq %rax, %r14
movq %rbx, %rdi
movq %r13, %rsi
callq 0xf251
movq %rax, %r13
movq %rbx, %rdi
movq %r12, %rsi
callq 0xede1
movq %r15, %rdi
callq 0xc6a0
movq %rax, %r15
movq %r14, 0x40(%rax)
movq %rbp, 0x50(%rax)
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd14c
testb %al, %al
jne 0xd080
movq %rbx, %rdi
movq %r15, %rsi
callq 0xc828
movq %rbx, %rdi
movq %r14, %rsi
callq 0xede1
movq %rbx, %rdi
movq %r12, %rsi
callq 0xed54
leaq 0x20(%rsp), %rdx
movq 0x10(%rdx), %rax
testq %rax, %rax
movq %r14, %rcx
cmovneq %rax, %rcx
movq %rbx, %rdi
movq %r13, %rsi
callq 0x1074b
movq %r15, %rdi
callq 0xc6cd
movq %rax, %r15
movq %rbx, %rdi
movq %r14, %rsi
callq 0xed54
movq %r15, %rdi
callq 0xc6cd
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 0xed54
movq %r12, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xc6cd
xorl %r14d, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0xf184
leaq 0x80ee(%rip), %rsi      # 0x15222
movl $0x61, %edi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xafeb