// File: /workspace/github_c_makefile_star2_O3/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 0x55db
leaq 0x9dab(%rip), %rax      # 0xec80
movslq (%rax,%r12,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movl -0x34(%rbp), %r14d
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
callq 0xaefc
movl %r14d, %edi
callq 0xafac
cmpl $0x2, %r12d
leaq 0xa1fd(%rip), %rax      # 0xf10f
leaq 0xa1fb(%rip), %rdi      # 0xf114
cmoveq %rax, %rdi
jmp 0x50a4
xorl %r14d, %r14d
cmpl $0xa, %r12d
setne %r14b
movq -0x78(%rbp), %r15
movq %rbx, %rdi
movq %r15, %rsi
callq 0x592e
movl $0x1, %edi
callq 0xa7ef
movl -0x34(%rbp), %ebx
movl %r14d, %edi
movq %r15, %rsi
movl %ebx, %edx
callq 0x5a27
leaq 0xa1bc(%rip), %rsi      # 0xf119
movq %r15, %rdi
callq 0x95dd
movl %eax, %edi
callq 0xae69
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0xa7ef
movl %r14d, %edi
movq %r15, %rsi
movl %ebx, %edx
jmp 0x519f
movq %rbx, %rdi
callq 0x245c
movl %eax, %r15d
movq %rbx, %rdi
callq 0x245c
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e8f
leaq 0xa25d(%rip), %r13      # 0xf20c
movq %r12, %rdi
movq %r13, %rsi
callq 0x95dd
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0xab15
movq -0x70(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e8f
callq 0xadc9
movq %r12, %rdi
movq %r13, %rsi
callq 0x95dd
movl %eax, %edi
movl %r15d, %esi
movl $0xfffffff8, %edx       # imm = 0xFFFFFFF8
callq 0xab15
callq 0xadc9
movl $0x1, %edi
callq 0xa7ef
leaq 0xacce(%rip), %rsi      # 0xfcd8
movl %r14d, %edi
callq 0xaac7
leaq 0xa20a(%rip), %rbx      # 0xf223
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x1070
callq 0xadc9
xorl %edi, %edi
callq 0xa7ef
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 0x592e
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
callq 0xadf1
jmp 0x54fa
movq -0x78(%rbp), %rsi
leaq 0xa063(%rip), %rdx      # 0xf0e3
movq %rbx, %rdi
callq 0x4b6c
movl -0x2c(%rbp), %edi
testl %edi, %edi
je 0x55db
callq 0xa7ef
callq 0xaefc
leaq 0xa06b(%rip), %rdi      # 0xf10f
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xaec4
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
movl -0x34(%rbp), %ebx
leaq 0xa038(%rip), %rdi      # 0xf114
callq 0xaec4
movl %ebx, %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb023
movl -0x60(%rbp), %edi
jmp 0x55fd
leaq -0x48(%rbp), %r12
movq -0x10(%r12), %r14
leaq -0x178(%rbp), %rdi
movl $0xa, %ecx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r12, %rdi
callq 0x5804
movl %eax, %r15d
testb $0x1, %r15b
jne 0x573b
shll $0x3, %r15d
callq 0xbd82
movq %rbx, %rdi
movq %r12, %rsi
callq 0x5753
movl $0x4, %edi
cmpl $0x7, -0x178(%rbp)
je 0x5168
leaq 0x97ed(%rip), %rsi      # 0xe947
leaq -0x178(%rbp), %rdi
callq 0x95dd
movl %eax, %edi
movq %r14, %rsi
movl %r15d, %edx
callq 0xa953
jmp 0x55db
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4e8f
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
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 0x5a27
movq -0x78(%rbp), %rsi
leaq 0x9d35(%rip), %rdx      # 0xeef5
movq %rbx, %rdi
callq 0x587e
movq -0x70(%rbp), %r14
movq %r14, %rdi
callq 0x95ca
testl %eax, %eax
jne 0x5747
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4e8f
jmp 0x536d
movq %rbx, %rdi
callq 0x245c
movl %eax, %r15d
movq %rbx, %rdi
callq 0x245c
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e8f
leaq 0x9fde(%rip), %r13      # 0xf1f6
movq %r12, %rdi
movq %r13, %rsi
callq 0x95dd
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0xaba6
movq -0x70(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e8f
callq 0xadc9
movq %r12, %rdi
movq %r13, %rsi
callq 0x95dd
movl %eax, %edi
movl %r15d, %esi
movl $0xfffffff8, %edx       # imm = 0xFFFFFFF8
callq 0xaba6
callq 0xadc9
xorl %edi, %edi
callq 0xa7ef
leaq 0xaa7f(%rip), %rsi      # 0xfcef
movl %r14d, %edi
callq 0xaac7
movl %r15d, %edi
callq 0xac74
callq 0xadc9
movl $0x1, %edi
callq 0xa7ef
movl %r14d, %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xac74
cmpl $0x2, -0xd8(%rbp)
jne 0x55b8
movl -0x38(%rbp), %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa824
movq -0x50(%rbp), %rsi
leaq 0x10(%rbx), %rdi
callq 0x5d9b
movl 0x10(%rbx), %edi
decl %edi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa865
movq %rbx, %rdi
callq 0x245c
movl %eax, %r15d
movq %rbx, %rdi
callq 0x245c
movl %eax, %r14d
movq -0x78(%rbp), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x4e8f
leaq 0x9a87(%rip), %rsi      # 0xeda9
movq %r12, %rdi
callq 0x95dd
movl %eax, %edi
movl %r15d, %esi
xorl %edx, %edx
callq 0xab15
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
leaq 0x9adf(%rip), %rsi      # 0xee28
movl %r14d, %edi
callq 0xaac7
movl %r15d, %edi
callq 0xac74
movq -0x68(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
movl %r14d, %edi
callq 0xac74
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xadf1
movl -0x80(%rbp), %r15d
cmpq $0x7, %r15
ja 0x55db
leaq 0x9958(%rip), %rax      # 0xecf0
movslq (%rax,%r15,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x592e
movl $0x1, %edi
callq 0xa7ef
xorl %edi, %edi
cmpl $0x4, %r15d
setne %dil
movl -0x34(%rbp), %edx
movq %r14, %rsi
callq 0x5a27
leaq -0x178(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x9e76(%rip), %rsi      # 0xf261
jmp 0x5516
movq -0x58(%rbp), %r14
movslq -0x48(%rbp), %r15
testq %r15, %r15
jle 0x55ed
movq -0x40(%rbp), %r12
leaq 0x1(%r15), %r13
movq -0x10(%r12,%r13,8), %rsi
movq %rbx, %rdi
callq 0x4e8f
decq %r13
cmpq $0x1, %r13
ja 0x5409
movq %rbx, %rdi
movq %r14, %rsi
callq 0x58c4
testl %r15d, %r15d
jle 0x55f8
incl %r15d
callq 0xadc9
decl %r15d
cmpl $0x1, %r15d
ja 0x5436
jmp 0x55f8
movq -0x78(%rbp), %rsi
leaq 0x9c44(%rip), %rdx      # 0xf098
movq %rbx, %rdi
callq 0x4b44
movq -0x70(%rbp), %rsi
leaq 0x9c56(%rip), %rdx      # 0xf0bd
movq %rbx, %rdi
callq 0x4b6c
movl -0x30(%rbp), %edi
callq 0xb563
movl $0x22f95, %edi          # imm = 0x22F95
jmp 0x55fd
movq -0x58(%rbp), %rbx
leaq 0x9cb1(%rip), %rdi      # 0xf13d
movq %rbx, %rsi
xorl %eax, %eax
callq 0x1070
movl -0xd8(%rbp), %r14d
movq %rbx, %rdi
callq 0xa8ff
cmpl $0x2, %r14d
je 0x55db
leaq 0x9ca0(%rip), %rsi      # 0xf156
leaq -0x128(%rbp), %rdi
callq 0x95dd
movl %eax, %edi
callq 0xb0f7
jmp 0x55db
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x592e
movq -0x70(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
movl -0x84(%rbp), %edi
movl -0x34(%rbp), %edx
movq %r14, %rsi
callq 0x5a27
leaq -0x178(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x9d14(%rip), %rsi      # 0xf22a
movq %rax, %rdi
callq 0x95dd
movl %eax, %edi
callq 0xae69
jmp 0x55db
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa9da
leaq -0x178(%rbp), %r14
movl $0xa, %ecx
movq %r14, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x48(%rbp), %r15
movq -0x30(%r15), %rsi
movq %rbx, %rdi
callq 0x4e8f
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5753
leaq 0x9901(%rip), %rdi      # 0xee78
callq 0xb215
movl $0x4, %ebx
cmpl $0x7, (%r14)
je 0x559c
leaq 0x93b9(%rip), %rsi      # 0xe947
leaq -0x178(%rbp), %rdi
callq 0x95dd
movl %eax, %ebx
callq 0xbd82
leaq 0x98d0(%rip), %rsi      # 0xee78
movl %ebx, %edi
callq 0xaa02
jmp 0x55db
movl $0x7b, %edi
jmp 0x55fd
leaq 0x9b6a(%rip), %rsi      # 0xf129
leaq -0x128(%rbp), %rbx
movq %rbx, %rdi
callq 0x95dd
movl 0xf0(%rbx), %esi
movl %eax, %edi
callq 0xa89a
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movq %r14, %rsi
callq 0x58c4
movl $0x1538, %edi           # imm = 0x1538
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa7ef
movq -0x78(%rbp), %rsi
jmp 0x56e7
movq 0xb0(%r14), %rsi
movq %rbx, %rdi
callq 0x4e8f
leaq -0x178(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
cmpl $0x1, (%rax)
jne 0x564e
cmpl $0x2, -0xd8(%rbp)
je 0x55db
leaq 0x9c3b(%rip), %rsi      # 0xf290
leaq -0x178(%rbp), %rdi
jmp 0x54bd
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
leaq 0x9be8(%rip), %rdi      # 0xf25c
jmp 0x56c2
movq -0x78(%rbp), %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x4e8f
leaq 0x9bb4(%rip), %rsi      # 0xf240
movq %r14, %rdi
callq 0x95dd
addq $0x158, %rsp            # imm = 0x158
cmpl $0x8, %eax
jne 0x5700
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xb0d1
movq -0x78(%rbp), %rsi
movq %rbx, %rdi
callq 0x4e8f
leaq 0x9b95(%rip), %rdi      # 0xf257
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xaf4c
movq -0x78(%rbp), %rsi
cmpl $0x1, (%rsi)
jne 0x570f
cmpl $0x2, 0x50(%rsi)
jne 0x570f
movq %rbx, %rdi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4e8f
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xaf24
leaq 0x9b5a(%rip), %rdx      # 0xf270
movq %rbx, %rdi
addq $0x158, %rsp            # imm = 0x158
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4b44
leaq 0x992a(%rip), %rdi      # 0xf060
callq 0x9581
leaq 0x973a(%rip), %rdi      # 0xee7c
callq 0x9581
leaq 0x9a1d(%rip), %rdi      # 0xf16b
callq 0x9546