// File: /workspace/github_c_makefile_star2_O3/Yamsman[P]scc/src/gen.c
// Function: gen_expr_logic_andor
void gen_expr_logic_andor(asm_f *f, ast_n *n) {
	//Logical-and expressions can short circuit if the LHS is 0,
	//and logical-or expressions can if the LHS is 1
	int jmp_i = -1;
	int pass_val = -1;
	char *lbl_sc = gen_numlabel(f);
	char *lbl_end = gen_numlabel(f);
	switch (n->dat.expr.kind) {
		case EXPR_LOGIC_AND: jmp_i = INST_JNZ; pass_val = 0; break;
		case EXPR_LOGIC_OR:  jmp_i = INST_JZ;  pass_val = 1; break;
	}

	//Generate LHS, compare the pass_value, and short-circuit if possible
	gen_expr(f, n->dat.expr.left);
	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_sc)));

	//Generate RHS, compare the pass_value, and short-circuit if possible
	gen_expr(f, n->dat.expr.right);
	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_sc)));

	//If this point was reached, 'and' is true or 'or' is false
	asmf_add_inst(f, mk_inst(INST_MOV, 2,
		mk_oprd(OPRD_REG, RAX),
		mk_oprd(OPRD_IMM, !pass_val)
	));
	asmf_add_inst(f, mk_inst(INST_JZ, 1, mk_oprd_label(lbl_end)));

	//Short-circuit result
	asmf_add_inst(f, mk_label(lbl_sc));
	asmf_add_inst(f, mk_inst(INST_MOV, 2,
		mk_oprd(OPRD_REG, RAX),
		mk_oprd(OPRD_IMM, pass_val)
	));
	asmf_add_inst(f, mk_label(lbl_end));

	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rsi, %r13
movq %rdi, %rbx
callq 0x3e80
movq %rax, %r15
movq %rbx, %rdi
callq 0x3e80
movq %rax, 0x50(%rsp)
movl 0x8(%r13), %eax
xorl %r12d, %r12d
cmpl $0x1, %eax
je 0x3f22
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpl $0x2, %eax
jne 0x3f27
xorl %ecx, %ecx
movl $0x1, %r12d
jmp 0x3f27
movl $0x1, %ecx
movl %ecx, 0x4c(%rsp)
movq 0x20(%r13), %rsi
movq %rbx, %rdi
callq 0x41eb
leaq 0x198(%rsp), %rbp
movq %rbp, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
leaq 0x178(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%rbp), %xmm0
movups 0x10(%rbp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x3d, %edi
movl $0x2, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
leaq 0x158(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x52c0
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x39, %edi
movl $0x1, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
movq 0x28(%r13), %rsi
movq %rbx, %rdi
callq 0x41eb
leaq 0x138(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
leaq 0x118(%rsp), %r13
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x3d, %edi
movl $0x2, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
leaq 0xf8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x52c0
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x39, %edi
movl $0x1, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
leaq 0xd8(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
leaq 0xb8(%rsp), %r13
movq %r13, %rdi
movl $0x1, %esi
movl %r12d, %edx
callq 0x52a0
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x3e, %edi
movl $0x2, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
leaq 0x98(%rsp), %r14
movq %r14, %rdi
movq 0x50(%rsp), %r12
movq %r12, %rsi
callq 0x52c0
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x39, %edi
movl $0x1, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
movq %r15, %rdi
callq 0x53b4
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
leaq 0x78(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x52a0
leaq 0x58(%rsp), %r15
movq %r15, %rdi
movl $0x1, %esi
movl 0x4c(%rsp), %edx
callq 0x52a0
movups (%r15), %xmm0
movups 0x10(%r15), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl $0x3e, %edi
movl $0x2, %esi
xorl %eax, %eax
callq 0x52d5
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
movq %r12, %rdi
callq 0x53b4
movq %rbx, %rdi
movq %rax, %rsi
callq 0x55c6
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq