// File: /workspace/github_c_makefile_star2_O0/Yamsman[P]scc/src/gen.c
// Function: gen_stmt_loop
void gen_stmt_loop(asm_f *f, ast_n *n) {
	char *lbl_beg = gen_numlabel(f);
	char *lbl_end = NULL;
	asmf_add_inst(f, mk_label(lbl_beg));

	//Condition for while and for loops
	if (n->dat.stmt.kind == STMT_WHILE) {
		lbl_end = gen_numlabel(f);
		
		//Does not apply for converted for loops with no condition
		if (n->dat.stmt.expr != NULL) {
			gen_expr(f, n->dat.stmt.expr);
			asmf_add_inst(f, mk_inst(INST_TEST, 2,
				mk_oprd(OPRD_REG, RAX),
				mk_oprd(OPRD_REG, RAX)
			));
			asmf_add_inst(f, mk_inst(INST_JZ, 1,
				mk_oprd_label(lbl_end)
			));
		}
	}
	
	//Generate loop body by hand to account for break/continue
	ast_n *n_cur = n->dat.stmt.body;
	if (n_cur->dat.stmt.kind == STMT_CMPD)
		n_cur = n_cur->next;
	while (n_cur != NULL) {
		f->cont_tgt = lbl_beg;
		f->break_tgt = lbl_end;
		switch (n_cur->kind) {
			case DECL: gen_decl(f, n_cur); break;
			case STMT: gen_stmt(f, n_cur); break;
		}
		n_cur = n_cur->next;
	}
	f->cont_tgt = NULL;
	f->break_tgt = NULL;

	//Condition for do-while loop
	if (n->dat.stmt.kind == STMT_DO_WHILE) {
		gen_expr(f, n->dat.stmt.expr);
		asmf_add_inst(f, mk_inst(INST_TEST, 2,
			mk_oprd(OPRD_REG, RAX),
			mk_oprd(OPRD_REG, RAX)
		));
		asmf_add_inst(f, mk_inst(INST_JNZ, 1,
			mk_oprd_label(lbl_beg)
		));
	} else {
		//Jump to beginning for while/for loops
		asmf_add_inst(f, mk_inst(INST_JMP, 1,
			mk_oprd_label(lbl_beg)
		));
	}

	//End label
	if (lbl_end != NULL)
		asmf_add_inst(f, mk_label(lbl_end));
	return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
callq 0x43f0
movq %rax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x18(%rbp), %rdi
callq 0x65a0
movq -0x110(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
movq -0x10(%rbp), %rax
cmpl $0x4, 0x8(%rax)
jne 0x5b08
movq -0x8(%rbp), %rdi
callq 0x43f0
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x5b06
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x4920
movq -0x8(%rbp), %rax
movq %rax, -0x120(%rbp)
leaq -0x40(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x63c0
leaq -0x60(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x63c0
movl $0x3d, %edi
movl $0x2, %esi
leaq -0x40(%rbp), %rcx
leaq -0x60(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq (%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x28(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x30(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x38(%rsp)
movb $0x0, %al
callq 0x6460
movq -0x120(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
movq -0x8(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x20(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0x6420
movl $0x39, %edi
movl $0x1, %esi
leaq -0x80(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
movb $0x0, %al
callq 0x6460
movq -0x118(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
jmp 0x5b08
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpl $0x1, 0x8(%rax)
jne 0x5b36
movq -0x88(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x88(%rbp)
jmp 0x5b38
cmpq $0x0, -0x88(%rbp)
je 0x5bb2
movq -0x18(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x88(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x124(%rbp)
testl %eax, %eax
je 0x5b7c
jmp 0x5b6f
movl -0x124(%rbp), %eax
subl $0x2, %eax
je 0x5b8e
jmp 0x5b9e
movq -0x8(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x4470
jmp 0x5b9e
movq -0x8(%rbp), %rdi
movq -0x88(%rbp), %rsi
callq 0x5540
movq -0x88(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x88(%rbp)
jmp 0x5b38
movq -0x8(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x8(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x10(%rbp), %rax
cmpl $0x6, 0x8(%rax)
jne 0x5ced
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x4920
movq -0x8(%rbp), %rax
movq %rax, -0x138(%rbp)
leaq -0xa8(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x63c0
leaq -0xc8(%rbp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x63c0
movl $0x3d, %edi
movl $0x2, %esi
leaq -0xa8(%rbp), %rcx
leaq -0xc8(%rbp), %rax
movq (%rcx), %rdx
movq %rdx, (%rsp)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rsp)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rsp)
movq (%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x28(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x30(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x38(%rsp)
movb $0x0, %al
callq 0x6460
movq -0x138(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
movq -0x8(%rbp), %rax
movq %rax, -0x130(%rbp)
movq -0x18(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
callq 0x6420
movl $0x3b, %edi
movl $0x1, %esi
leaq -0xe8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
movb $0x0, %al
callq 0x6460
movq -0x130(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
jmp 0x5d51
movq -0x8(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x18(%rbp), %rsi
leaq -0x108(%rbp), %rdi
callq 0x6420
movl $0x45, %edi
movl $0x1, %esi
leaq -0x108(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
movb $0x0, %al
callq 0x6460
movq -0x140(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
cmpq $0x0, -0x20(%rbp)
je 0x5d7b
movq -0x8(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x20(%rbp), %rdi
callq 0x65a0
movq -0x148(%rbp), %rdi
movq %rax, %rsi
callq 0x68f0
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
nopw %cs:(%rax,%rax)