// File: /workspace/github_c_makefile_star2_O2/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, %r12
movq %rdi, %rbx
callq 0x3d40
movq %rax, %r15
movq %rbx, %rdi
callq 0x3d40
movl 0x8(%r12), %ecx
cmpl $0x1, %ecx
movq %rax, 0x50(%rsp)
je 0x3deb
cmpl $0x2, %ecx
jne 0x3df7
movl $0x0, 0x4c(%rsp)
pushq $0x1
popq %rax
movl %eax, 0x48(%rsp)
jmp 0x3e06
movl $0x0, 0x48(%rsp)
pushq $0x1
jmp 0x3e01
movl $0x0, 0x48(%rsp)
pushq $-0x1
popq %rax
movl %eax, 0x4c(%rsp)
movq 0x20(%r12), %rsi
movq %rbx, %rdi
callq 0x40b5
leaq 0x198(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
leaq 0x178(%rsp), %r13
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
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)
pushq $0x3d
popq %rdi
pushq $0x2
popq %r13
movl %r13d, %esi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
leaq 0x158(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x50ed
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
pushq $0x39
popq %rbp
pushq $0x1
popq %rsi
movl %ebp, %edi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
movq 0x28(%r12), %rsi
movq %rbx, %rdi
callq 0x40b5
leaq 0x138(%rsp), %r12
movq %r12, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
leaq 0x118(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%r12), %xmm0
movups 0x10(%r12), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
pushq $0x3d
popq %rdi
movl %r13d, %esi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
leaq 0xf8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x50ed
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl %ebp, %edi
pushq $0x1
popq %rbp
movl %ebp, %esi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
leaq 0xd8(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
leaq 0xb8(%rsp), %r12
movq %r12, %rdi
movl %ebp, %esi
movl 0x48(%rsp), %edx
callq 0x50d0
movups (%r12), %xmm0
movups 0x10(%r12), %xmm1
movups %xmm1, 0x30(%rsp)
movups %xmm0, 0x20(%rsp)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
pushq $0x3e
popq %r12
movl %r12d, %edi
movl %r13d, %esi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
leaq 0x98(%rsp), %r14
movq %r14, %rdi
movq 0x50(%rsp), %r13
movq %r13, %rsi
callq 0x50ed
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
pushq $0x39
popq %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
movq %r15, %rdi
callq 0x51dd
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
leaq 0x78(%rsp), %r14
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x50d0
leaq 0x58(%rsp), %r15
movq %r15, %rdi
movl %ebp, %esi
movl 0x4c(%rsp), %edx
callq 0x50d0
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 %r12d, %edi
pushq $0x2
popq %rsi
xorl %eax, %eax
callq 0x50ff
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
movq %r13, %rdi
callq 0x51dd
movq %rbx, %rdi
movq %rax, %rsi
callq 0x53ce
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq