// File: /workspace/github_c_makefile_star2_O2/hsjoihs[P]c-compiler/codegen_expression.c
// Function: print_expression
void print_expression(struct PrinterState *ptr_prs, const struct Expr *ref_expr)
{
	const struct Expr expr = *ref_expr;
	switch (expr.category) {
	case FPCALL_EXPR_RETURNING_INTEGER_CLASS:
	case FPCALL_EXPR_RETURNING_MEMORY_CLASS:
	case FUNCCALL_EXPR_RETURNING_INTEGER_CLASS:
	case FUNCCALL_EXPR_RETURNING_MEMORY_CLASS: {
		unsupported("struct/union returned by function used as a pure rvalue");
	}
	case STRUCT_OR_UNION_ASSIGNMENT_EXPR: {
		print_address_of_lvalue(
		    ptr_prs, expr.ptr1, "left hand of struct/union assignment");
		print_address_of_lvalue_or_struct_or_union(
		    ptr_prs, expr.ptr2, "right hand of struct/union assignment");
		int size = expr.size_info_for_struct_or_union_assign;
		gen_copy_1st_struct_or_union_to_2nd_and_discard(size);
		gen_push_int(143253); /* random garbage */
		return;
	}
	case VOID_EXPR: {
		gen_push_int(123); /* random garbage */
		return;
	}
	case NULLPTR: {
		gen_push_nullptr();
		return;
	}
	case PTR_STRUCT_AND_OFFSET: {
		print_address_of_lvalue_or_struct_or_union(
		    ptr_prs, expr.ptr1, "struct/union whose member is to be accessed");
		int offset = expr.struct_offset;
		if (offset) {
			gen_push_int(offset);
			gen_cltq();
			gen_op_8byte("addq");
		}
		return;
	}
	case POINTER_MINUS_POINTER: {
		print_expression(ptr_prs, expr.ptr1);
		print_expression(ptr_prs, expr.ptr2);
		int size = expr.size_info_for_pointer_arith;
		gen_op_8byte("subq");
		gen_div_by_const(size);
		return;
	}
	case POINTER_PLUS_INT:
	case POINTER_MINUS_INT: {
		int size = expr.size_info_for_pointer_arith;
		print_expression(ptr_prs, expr.ptr1);
		print_expression(ptr_prs, expr.ptr2);
		print_op_pointer_plusminus_int(expr.category == POINTER_PLUS_INT, size);
		return;
	}
	case POSTFIX_INCREMENT:
	case POSTFIX_DECREMENT: {
		enum SimpleBinOp opkind2 = expr.category == POSTFIX_INCREMENT
		                               ? SIMPLE_BIN_OP_PLUS
		                               : SIMPLE_BIN_OP_MINUS;

		print_expression_as_lvalue(ptr_prs, expr.ptr1);
		gen_push_int(1);

		print_simple_binary_op(opkind2, &expr.ptr1->details.type,
		                       expr.size_info_for_pointer_arith);

		gen_assign_nbyte(
		    size_of_basic(&expr.ptr1->details.type, "postfix inc/dec"));

		gen_push_int(-1);

		print_simple_binary_op(opkind2, &expr.ptr1->details.type,
		                       expr.size_info_for_pointer_arith);

		return;
	}

	case LOCAL_VAR_: {
		if (expr.details.true_type.type_category == ARRAY) {
			gen_push_address_of_local(expr.local_var_offset);
			return;
		}
		gen_push_from_local_nbyte(
		    size_of_basic(&expr.details.type, "local var as rvalue"),
		    expr.local_var_offset);

		return;
	}

	case GLOBAL_VAR_: {
		printf("//global `%s` as rvalue\n", expr.global_var_name);

		if (expr.details.true_type.type_category == ARRAY) {
			gen_push_address_of_global(expr.global_var_name);
			return;
		}

		gen_push_address_of_global(expr.global_var_name);
		gen_peek_and_dereference_nbyte(
		    size_of_basic(&expr.details.type, "global var as rvalue"));

		return;
	}

	case SIMPLE_BINARY_EXPR: {
		print_expression(ptr_prs, expr.ptr1);
		print_expression(ptr_prs, expr.ptr2);
		print_simple_binary_op(expr.simple_binary_operator,
		                       &expr.ptr1->details.type,
		                       expr.size_info_for_pointer_arith);
		return;
	}

	case COMMA_EXPR: {
		print_expression_or_addr_of_struct_or_union(
		    ptr_prs, expr.ptr1, "struct as the first operand of comma");

		if (is_struct_or_union(&expr.ptr2->details.type)) {
			simple_error("struct/union is used as the right operand of comma "
			             "operator, but the result of comma expression is used "
			             "in a non-struct/non-union manner.\n");

		} else {
			print_expression(ptr_prs, expr.ptr2);
		}

		gen_discard2nd();
		return;
	}

	case LOGICAL_OR_EXPR: {

		int label1 = get_new_label_name(ptr_prs);
		int label2 = get_new_label_name(ptr_prs);
		print_expression(ptr_prs, expr.ptr1);

		gen_if_nonzero_jmp_nbyte(
		    size_of_basic(&expr.ptr1->details.type, "operand of logical or"),
		    label1, 0);
		print_expression(ptr_prs, expr.ptr2);
		gen_discard();
		gen_if_nonzero_jmp_nbyte(
		    size_of_basic(&expr.ptr2->details.type, "operand of logical or"),
		    label1, -8);
		gen_discard();
		gen_push_int(0);
		gen_jump(label2, "logical OR");
		gen_label(label1);
		gen_discard();
		gen_push_int(1);
		gen_label(label2);
		return;
	}
	case LOGICAL_AND_EXPR: {

		int label1 = get_new_label_name(ptr_prs);
		int label2 = get_new_label_name(ptr_prs);
		print_expression(ptr_prs, expr.ptr1);

		gen_if_zero_jmp_nbyte(
		    size_of_basic(&expr.ptr1->details.type, "operand of logical and"),
		    label1, 0);
		print_expression(ptr_prs, expr.ptr2);
		gen_discard();
		gen_if_zero_jmp_nbyte(
		    size_of_basic(&expr.ptr2->details.type, "operand of logical and"),
		    label1, -8);
		gen_discard();
		gen_push_int(1);
		gen_jump(label2, "logical AND");
		printf(".L%d:\n", label1);
		gen_discard();
		gen_push_int(0);
		printf(".L%d:\n", label2);
		return;
	}

	case ASSIGNMENT_EXPR: {

		print_expression_as_lvalue(ptr_prs, expr.ptr1);
		print_expression(ptr_prs, expr.ptr2);

		gen_discard2nd();

		struct Type type = expr.ptr1->details.type;

		gen_assign_nbyte(size_of_basic(&type, "operand of assignment"));

		return;
	}
	case COMPOUND_ASSIGNMENT_EXPR: {

		print_expression_as_lvalue(ptr_prs, expr.ptr1);
		print_expression(ptr_prs, expr.ptr2);

		print_simple_binary_op(expr.simple_binary_operator,
		                       &expr.ptr1->details.type,
		                       expr.size_info_for_pointer_arith);

		struct Type type = expr.ptr1->details.type;

		gen_assign_nbyte(size_of_basic(&type, "operand of assignment"));

		return;
	}
	case INT_VALUE:
		gen_push_int(expr.int_value);
		return;
	case UNARY_OP_EXPR:
		switch (expr.unary_operator) {
		case UNARY_OP_NOT: {
			print_expression(ptr_prs, expr.ptr1);
			if (size_of_basic(&expr.ptr1->details.type,
			                  "operand of logical not") == 8) {
				gen_logical_not_of_pointer();
			} else {
				gen_unary_not();
			}
			return;
		}
		case UNARY_OP_TILDA:
			print_expression(ptr_prs, expr.ptr1);
			gen_unary("notl");
			return;
		case UNARY_OP_PLUS:
			print_expression(ptr_prs, expr.ptr1);
			/* do nothing */
			return;
		case UNARY_OP_MINUS:
			print_expression(ptr_prs, expr.ptr1);
			gen_unary("negl");
			return;

		case UNARY_OP_PLUS_PLUS:
		case UNARY_OP_MINUS_MINUS: {
			print_expression_as_lvalue(ptr_prs, expr.ptr1);

			gen_push_int(1);
			print_simple_binary_op(
			    expr.unary_operator == UNARY_OP_PLUS_PLUS ? SIMPLE_BIN_OP_PLUS
			                                              : SIMPLE_BIN_OP_MINUS,
			    &expr.ptr1->details.type, expr.size_info_for_pointer_arith);

			struct Type type = expr.ptr1->details.type;

			gen_assign_nbyte(size_of_basic(&type, "prefix inc/dec"));
			return;
		}

		case UNARY_OP_AND: {
			struct Type type = expr.ptr1->details.type;
			struct Type true_type = expr.ptr1->details.true_type;
			if (type.type_category == PTR_ &&
			    true_type.type_category == ARRAY) {
				print_expression(ptr_prs, expr.ptr1);
			} else {
				print_address_of_lvalue(
				    ptr_prs, expr.ptr1, "address requested by & operator");
			}
			return;
		}

		case UNARY_OP_ASTERISK: {
			print_expression(ptr_prs, expr.ptr1);
			struct Type type = expr.details.type;
			struct Type true_type = expr.details.true_type;

			if (type.type_category == PTR_ &&
			    true_type.type_category == ARRAY) {
				/* do not dereference, if it is an array */
				return;
			}
			gen_peek_and_dereference_nbyte(
			    size_of_basic(&type, "*expr as rvalue"));

			return;
		}
		}
		return;
	case CONDITIONAL_EXPR: {
		int label1 = get_new_label_name(ptr_prs);
		int label2 = get_new_label_name(ptr_prs);

		print_expression(ptr_prs, expr.ptr1);
		gen_if_zero_jmp_nbyte(
		    size_of_basic(&expr.ptr1->details.type,
		                  "condition of conditional expression"),
		    label1, 0);
		print_expression(ptr_prs, expr.ptr2);
		gen_jump(label2, "ternary operator");
		gen_label(label1);
		print_expression(ptr_prs, expr.ptr3);
		gen_label(label2);
		gen_discard2nd();
		return;
	}
	case FPCALL_EXPR: {
		struct Type ret_type = expr.details.type;

		print_expression(ptr_prs, expr.ptr1);
		pass_args(ptr_prs, &expr.args);
		gen_pop_to_reg_8byte("r11");

		int size = ret_type.type_category == VOID_
		               ? 4 /* for convenience */
		               : size_of_basic(&ret_type, "return value");

		gen_raw_call_partA();
		gen_call_reg_and_push_ret_of_nbyte(size, "r11");

		return;
	}
	case FUNCCALL_EXPR: {
		const char *ident_str = expr.global_var_name;
		struct Type ret_type = expr.details.type;

		int arg_stacksize = count_args(&expr.args) * 8;
		if (arg_stacksize % 16 != 0) {
			unsupported("misaligned stack");
		}
		gen_raw_call_partA();
		pass_args(ptr_prs, &expr.args);

		int size = ret_type.type_category == VOID_
		               ? 4 /* for convenience */
		               : size_of_basic(&ret_type, "return value");

		gen_push_ret_of_nbyte(size, ident_str, arg_stacksize);

		return;
	}
	case BUILTIN_FUNCCALL_EXPR: {
		const char *ident_str = expr.global_var_name;

		for (int counter = expr.args.length - 1; counter >= 0; counter--) {
			const struct Expr *ptr_expr_ = expr.args.vector[counter];

			print_expression(ptr_prs, ptr_expr_);
		}

		handle_builtin(ptr_prs, ident_str);

		for (int counter = expr.args.length - 1; counter >= 0; counter--) {
			gen_discard();
		}
		gen_push_int(5432); /* a dummy value to be discarded */

		return;
	}

	case STRING_LITERAL: {
		const char *str = expr.literal_string;
		push_vector(&ptr_prs->string_constant_pool, str);
		gen_push_address_of_str(ptr_prs->string_constant_pool.length - 1);
	}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x158, %rsp            # imm = 0x158
movq %rsi, %r15
movq %rdi, %rbx
leaq -0x128(%rbp), %r14
movl $0x100, %edx            # imm = 0x100
movq %r14, %rdi
callq 0x1100
movl 0xa0(%r14), %r12d
cmpq $0x1b, %r12
ja 0x42c7
leaq 0xa0cf(%rip), %rax      # 0xdca4
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movl -0x34(%rbp), %r14d
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
xorl %edi, %edi
cmpl $0x2, %r12d
sete %dil
movl %r14d, %esi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x45e4
xorl %r14d, %r14d
cmpl $0xa, %r12d
setne %r14b
movq -0x78(%rbp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x461a
pushq $0x1
popq %rdi
callq 0x96f1
movl -0x34(%rbp), %ebx
movl %r14d, %edi
movq %r15, %rsi
movl %ebx, %edx
callq 0x4713
leaq 0xa4e7(%rip), %rsi      # 0xe13d
movq %r15, %rdi
callq 0x81de
movl %eax, %edi
callq 0x9d4a
pushq $-0x1
popq %rdi
callq 0x96f1
movl %r14d, %edi
movq %r15, %rsi
movl %ebx, %edx
jmp 0x3e72
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r15d
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3b8f
leaq 0xa58a(%rip), %r13      # 0xe230
movq %r12, %rdi
movq %r13, %rsi
callq 0x81de
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0x9a17
movq -0x70(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3b8f
callq 0x9caa
movq %r12, %rdi
movq %r13, %rsi
callq 0x81de
pushq $-0x8
popq %rdx
movl %eax, %edi
movl %r15d, %esi
callq 0x9a17
callq 0x9caa
pushq $0x1
popq %rdi
callq 0x96f1
leaq 0xafff(%rip), %rsi      # 0xecfc
movl %r14d, %edi
callq 0x99c9
leaq 0xa53b(%rip), %rbx      # 0xe247
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
callq 0x9caa
xorl %edi, %edi
callq 0x96f1
movq %rbx, %rdi
movl %r14d, %esi
xorl %eax, %eax
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x1070
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x461a
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
callq 0x9cd2
jmp 0x41b6
movq -0x78(%rbp), %rsi
leaq 0xa394(%rip), %rdx      # 0xe107
movq %rbx, %rdi
callq 0x3832
movl -0x2c(%rbp), %edi
testl %edi, %edi
je 0x42c7
callq 0x96f1
callq 0x9ddd
leaq 0xa39c(%rip), %rdi      # 0xe133
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9da5
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movl -0x34(%rbp), %ebx
leaq 0xa369(%rip), %rdi      # 0xe138
callq 0x9da5
movl %ebx, %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9f02
movl -0x60(%rbp), %edi
jmp 0x4242
leaq -0x48(%rbp), %r12
movq -0x10(%r12), %r14
pushq $0xa
popq %rcx
leaq -0x178(%rbp), %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r12, %rdi
callq 0x44ba
movl %eax, %r15d
testb $0x1, %r15b
jne 0x43ff
shll $0x3, %r15d
callq 0xaadc
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4417
cmpl $0x7, -0x178(%rbp)
jne 0x42a7
pushq $0x4
popq %rdi
jmp 0x42bc
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3b8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movl -0x84(%rbp), %edi
movl -0x34(%rbp), %edx
movq %r14, %rsi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4713
movq -0x78(%rbp), %rsi
leaq 0xa086(%rip), %rdx      # 0xdf19
movq %rbx, %rdi
callq 0x4536
movq -0x70(%rbp), %r14
movq %r14, %rdi
callq 0x81cb
testl %eax, %eax
jne 0x440b
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3b8f
jmp 0x403c
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r15d
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3b8f
leaq 0xa32f(%rip), %r13      # 0xe21a
movq %r12, %rdi
movq %r13, %rsi
callq 0x81de
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0x9ab3
movq -0x70(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3b8f
callq 0x9caa
movq %r12, %rdi
movq %r13, %rsi
callq 0x81de
pushq $-0x8
popq %rdx
movl %eax, %edi
movl %r15d, %esi
callq 0x9ab3
callq 0x9caa
xorl %edi, %edi
callq 0x96f1
leaq 0xadd2(%rip), %rsi      # 0xed13
movl %r14d, %edi
callq 0x99c9
movl %r15d, %edi
callq 0x9b55
callq 0x9caa
pushq $0x1
popq %rdi
callq 0x96f1
movl %r14d, %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9b55
cmpl $0x2, -0xd8(%rbp)
jne 0x4258
movl -0x38(%rbp), %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9726
movq -0x50(%rbp), %rsi
leaq 0x10(%rbx), %rdi
callq 0x4a57
movl 0x10(%rbx), %edi
decl %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9767
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r15d
movq %rbx, %rdi
callq 0x12a8
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x3b8f
leaq 0x9ddc(%rip), %rsi      # 0xddcd
movq %r12, %rdi
callq 0x81de
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0x9a17
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
leaq 0x9e34(%rip), %rsi      # 0xde4c
movl %r14d, %edi
callq 0x99c9
movl %r15d, %edi
callq 0x9b55
movq -0x68(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movl %r14d, %edi
callq 0x9b55
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9cd2
movl -0x80(%rbp), %r15d
cmpq $0x7, %r15
ja 0x42c7
leaq 0x9cad(%rip), %rax      # 0xdd14
movslq (%rax,%r15,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x461a
pushq $0x1
popq %rdi
callq 0x96f1
xorl %edi, %edi
cmpl $0x4, %r15d
setne %dil
movl -0x34(%rbp), %edx
movq %r14, %rsi
callq 0x4713
pushq $0xa
popq %rcx
leaq -0x178(%rbp), %rax
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0xa1cf(%rip), %rsi      # 0xe285
jmp 0x41d0
movq -0x58(%rbp), %r14
movl -0x48(%rbp), %r15d
movq -0x40(%rbp), %r12
movq %r15, %r13
testl %r13d, %r13d
jle 0x40e1
movq -0x8(%r12,%r13,8), %rsi
decq %r13
movq %rbx, %rdi
callq 0x3b8f
jmp 0x40ca
movq %rbx, %rdi
movq %r14, %rsi
callq 0x457c
testl %r15d, %r15d
jle 0x40fb
decl %r15d
callq 0x9caa
jmp 0x40ec
movl $0x1538, %edi           # imm = 0x1538
jmp 0x4242
movq -0x78(%rbp), %rsi
leaq 0x9fac(%rip), %rdx      # 0xe0bc
movq %rbx, %rdi
callq 0x37f0
movq -0x70(%rbp), %rsi
leaq 0x9fbe(%rip), %rdx      # 0xe0e1
movq %rbx, %rdi
callq 0x3832
movl -0x30(%rbp), %edi
callq 0xa3cd
movl $0x22f95, %edi          # imm = 0x22F95
jmp 0x4242
movq -0x58(%rbp), %rbx
leaq 0xa019(%rip), %rdi      # 0xe161
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1070
movl -0xd8(%rbp), %r14d
movq %rbx, %rdi
callq 0x9801
cmpl $0x2, %r14d
je 0x42c7
leaq 0xa008(%rip), %rsi      # 0xe17a
leaq -0x128(%rbp), %rdi
callq 0x81de
movl %eax, %edi
callq 0x9fd6
jmp 0x42c7
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x461a
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
movl -0x84(%rbp), %edi
movl -0x34(%rbp), %edx
movq %r14, %rsi
callq 0x4713
pushq $0xa
popq %rcx
leaq -0x178(%rbp), %rax
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0xa07e(%rip), %rsi      # 0xe24e
movq %rax, %rdi
callq 0x81de
movl %eax, %edi
callq 0x9d4a
jmp 0x42c7
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x98dc
pushq $0xa
popq %rcx
leaq -0x178(%rbp), %r14
movq %r14, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x48(%rbp), %r15
movq -0x30(%r15), %rsi
movq %rbx, %rdi
callq 0x3b8f
movq %rbx, %rdi
movq %r15, %rsi
callq 0x4417
leaq 0x9c6d(%rip), %rdi      # 0xde9c
callq 0xa0f4
cmpl $0x7, (%r14)
jne 0x427d
pushq $0x4
popq %rbx
jmp 0x4292
pushq $0x7b
popq %rdi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x96f1
leaq 0x9eee(%rip), %rsi      # 0xe14d
leaq -0x128(%rbp), %rbx
movq %rbx, %rdi
callq 0x81de
movl 0xf0(%rbx), %esi
movl %eax, %edi
callq 0x979c
jmp 0x42c7
leaq 0x96e7(%rip), %rsi      # 0xd96b
leaq -0x178(%rbp), %rdi
callq 0x81de
movl %eax, %ebx
callq 0xaadc
leaq 0x9bfe(%rip), %rsi      # 0xde9c
movl %ebx, %edi
callq 0x9904
jmp 0x42c7
leaq 0x96bd(%rip), %rsi      # 0xd96b
leaq -0x178(%rbp), %rdi
callq 0x81de
movl %eax, %edi
movq %r14, %rsi
movl %r15d, %edx
callq 0x9855
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x78(%rbp), %rsi
jmp 0x43ab
movq 0xb0(%r14), %rsi
movq %rbx, %rdi
callq 0x3b8f
pushq $0xa
popq %rcx
leaq -0x178(%rbp), %rax
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
cmpl $0x1, (%rax)
jne 0x4312
cmpl $0x2, -0xd8(%rbp)
je 0x42c7
leaq 0x9f9b(%rip), %rsi      # 0xe2b4
leaq -0x178(%rbp), %rdi
jmp 0x4179
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
leaq 0x9f48(%rip), %rdi      # 0xe280
jmp 0x4386
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3b8f
leaq 0x9f14(%rip), %rsi      # 0xe264
movq %r14, %rdi
callq 0x81de
addq $0x158, %rsp            # imm = 0x158
cmpl $0x8, %eax
jne 0x43c4
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9fb0
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x3b8f
leaq 0x9ef5(%rip), %rdi      # 0xe27b
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9e2d
movq -0x78(%rbp), %rsi
cmpl $0x1, (%rsi)
jne 0x43d3
cmpl $0x2, 0x50(%rsi)
jne 0x43d3
movq %rbx, %rdi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3b8f
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9e05
leaq 0x9eba(%rip), %rdx      # 0xe294
movq %rbx, %rdi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x37f0
leaq 0x9c8a(%rip), %rdi      # 0xe084
callq 0x8186
leaq 0x9a9a(%rip), %rdi      # 0xdea0
callq 0x8186
leaq 0x9d7d(%rip), %rdi      # 0xe18f
callq 0x814d