// File: /workspace/github_c_makefile_star2_O2/hsjoihs[P]c-compiler/typecheck_expression.c
// Function: typecheck_expression
struct Expr typecheck_expression(struct AnalyzerState *ptr_ps,
                                 const struct UntypedExpr *ref_uexpr)
{
	const struct UntypedExpr uexpr = *ref_uexpr;
	switch (uexpr.category) {
	case AMPERSAND_DOT: {
		struct Expr struct_or_union_expr =
		    typecheck_expression(ptr_ps, uexpr.ptr1);
		const char *ident_after_dot = uexpr.ident_after_dot;
		if (!is_struct_or_union(&struct_or_union_expr.details.type)) {
			fprintf(stderr, "member is requested but the left operand is "
			                "neither a struct nor a union\n");
			exit(EXIT_FAILURE);
		}

		const char *tag =
		    struct_or_union_expr.details.type.s.struct_or_union_tag;
		const struct StructOrUnionInternalCompleteInfo *ptr_info =
		    lookup(ptr_ps->global_struct_or_union_tag_map, tag);
		if (!ptr_info) {
			fprintf(stderr,
			        "tried to use a member of incomplete type `struct %s` / "
			        "`union %s`\n",
			        tag, tag);
			exit(EXIT_FAILURE);
		}

		struct Vector /* <TypeAndIdent> */ vec =
		    *ptr_info->info.ptr_types_and_idents;
		int nth_member = -1;

		struct Expr expr;
		for (int i = 0; i < vec.length; i++) {
			const struct TypeAndIdent *ptr_vec_i = vec.vector[i];
			if (strcmp(ptr_vec_i->ident_str, ident_after_dot) == 0) {
				nth_member = i;

				struct Type t2 = ptr_vec_i->type;
				struct Type t3 = ptr_to_type(&t2);
				expr.details.type = t3;
				expr.details.true_type = t3;
				break;
			}
		}

		if (nth_member == -1) {
			fprintf(stderr, "member `%s` does not belong to struct `%s`\n",
			        ident_after_dot, tag);
			exit(EXIT_FAILURE);
		}

		int offset = ptr_info->offset_vec[nth_member];

		struct Expr *ptr_struct_or_union_expr = calloc(1, sizeof(struct Expr));
		*ptr_struct_or_union_expr = struct_or_union_expr;

		expr.category = PTR_STRUCT_AND_OFFSET;
		expr.struct_offset = offset;
		expr.ptr1 = ptr_struct_or_union_expr;
		expr.ptr2 = 0;
		expr.ptr3 = 0;
		return expr;
	}
	case SIZEOF_TYPE: {
		struct Expr expr;
		expr.details.type = INT_TYPE();
		expr.int_value = size_of(ptr_ps, &uexpr.operand_of_sizeof_or_alignof);
		expr.category = INT_VALUE;
		return expr;
	}
	case ALIGNOF_TYPE: {
		struct Expr expr;
		expr.details.type = INT_TYPE();
		expr.int_value = align_of(ptr_ps, &uexpr.operand_of_sizeof_or_alignof);
		expr.category = INT_VALUE;
		return expr;
	}
	case UNARY_EXPR: {
		enum TokenKind kind = uexpr.operator_;
		const struct Expr expr = typecheck_expression(ptr_ps, uexpr.ptr1);
		return typecheck_unary_expression(ptr_ps, &expr, kind);
	}
	case FUNC_PTR_CALL: {
		struct Expr fp_expr = typecheck_expression(ptr_ps, uexpr.ptr1);

		struct Type fn_type;
		if (fp_expr.details.type.type_category == FN) {
			fn_type = fp_expr.details.type;
		} else if (fp_expr.details.type.type_category == PTR_ &&
		           fp_expr.details.type.derived_from->type_category == FN) {
			fn_type = *(fp_expr.details.type.derived_from);
		} else {
			fprintf(
			    stderr,
			    "function call operator was applied to something of type `");
			debug_print_type(&fp_expr.details.type);
			fprintf(stderr,
			        "`, which is neither a function nor a function pointer\n");
			exit(EXIT_FAILURE);
		}

		int param_infos_validity = fn_type.param_infos_validity;
		struct Vector /*<TypeAndIdent>*/ param_infos;

		if (param_infos_validity != INVALID) {
			param_infos = fn_type.param_infos;
		}

		struct Expr expr =
		    func_call_expr(ptr_ps, fn_type.derived_from,
		                   param_infos_validity != INVALID ? &param_infos : 0,
		                   &uexpr.arg_exprs_vec, 1 /* is_fp_call */);

		struct Expr *ptr_fp_expr = calloc(1, sizeof(struct Expr));
		*ptr_fp_expr = fp_expr;
		expr.ptr1 = ptr_fp_expr;

		return expr;
	}
	case BUILTIN_FUNCCALL: {
		const char *ident_str = uexpr.var_name;
		struct Expr expr = builtin_func_call_expr(ptr_ps, &uexpr.arg_exprs_vec);
		expr.global_var_name = ident_str;
		return expr;
	}
	case FUNCCALL: {
		const char *ident_str = uexpr.var_name;

		struct Type ret_type;

		int param_infos_validity;
		struct Vector /*<TypeAndIdent>*/ param_infos;
		if (!isElem(ptr_ps->func_info_map, ident_str)) {
			if (from_name_to_expr(ptr_ps, ident_str)) {
				struct UntypedExpr *p_fp_u =
				    calloc(1, sizeof(struct UntypedExpr));
				p_fp_u->category = VAR;
				p_fp_u->var_name = ident_str;

				struct UntypedExpr u = uexpr;
				u.category = FUNC_PTR_CALL;
				u.ptr1 = p_fp_u;

				return typecheck_expression(ptr_ps, &u);
			}
			fprintf(stderr, "Undeclared function `%s()` detected.\n",
			        ident_str);
			fprintf(stderr, "Assumes that `%s()` returns `int`\n", ident_str);
			ret_type = INT_TYPE();
			param_infos_validity = INVALID;
		} else {
			struct Type *ptr_func_info =
			    lookup(ptr_ps->func_info_map, ident_str);
			ret_type = *(ptr_func_info->derived_from);
			param_infos_validity = ptr_func_info->param_infos_validity;
			if (param_infos_validity != INVALID) {
				param_infos = ptr_func_info->param_infos;
			}
		}

		struct Expr expr =
		    func_call_expr(ptr_ps, &ret_type,
		                   param_infos_validity != INVALID ? &param_infos : 0,
		                   &uexpr.arg_exprs_vec, 0 /* is_fp_call */);
		expr.global_var_name = ident_str;
		return expr;
	}
	case POSTFIX_EXPR: {
		struct Expr expr = typecheck_expression(ptr_ps, uexpr.ptr1);
		struct Expr *ptr_expr1 = calloc(1, sizeof(struct Expr));
		*ptr_expr1 = expr;

		enum TokenKind opkind = uexpr.operator_;

		struct Expr new_expr;
		new_expr.details.type = expr.details.type;
		new_expr.details.true_type = expr.details.type;
		new_expr.category =
		    opkind == OP_PLUS_PLUS ? POSTFIX_INCREMENT : POSTFIX_DECREMENT;
		new_expr.ptr1 = ptr_expr1;
		new_expr.ptr2 = 0;
		new_expr.ptr3 = 0;
		if (expr.details.type.type_category == PTR_) {
			const struct Type deref = deref_type(&expr.details.type);
			new_expr.size_info_for_pointer_arith = size_of(ptr_ps, &deref);
		}

		return new_expr;
	}
	case INT_LITERAL_: {
		struct Expr expr;
		expr.details.type = INT_TYPE();
		expr.int_value = uexpr.int_value;
		expr.category = INT_VALUE;
		return expr;
	}
	case VAR: {
		struct Expr *p = from_name_to_expr(ptr_ps, uexpr.var_name);
		if (!p) {
			fprintf(stderr, "%s is not declared either globally or locally\n",
			        uexpr.var_name);
			exit(EXIT_FAILURE);
		}
		return *p;
	}
	case STRING_LITERAL_: {
		return string_literal(uexpr.literal_string);
	}
	case CONDITIONAL: {
		struct Expr expr = typecheck_expression(ptr_ps, uexpr.ptr1);
		struct Expr true_branch = typecheck_expression(ptr_ps, uexpr.ptr2);
		struct Expr false_branch = typecheck_expression(ptr_ps, uexpr.ptr3);

		if_function_cast_to_pointer(&true_branch);
		if_function_cast_to_pointer(&false_branch);

		if (false_branch.details.type.type_category == PTR_) {
			cast_to_null_pointer_if_possible(&true_branch,
			                                 &false_branch.details);
		} else if (true_branch.details.type.type_category == PTR_) {
			cast_to_null_pointer_if_possible(&false_branch,
			                                 &true_branch.details);
		}

		expect_type(ptr_ps, &false_branch.details.type,
		            &true_branch.details.type,
		            "mismatch of type between the false branch and the true "
		            "branch of a conditional operator");
		struct Expr *ptr_expr1 = calloc(1, sizeof(struct Expr));
		struct Expr *ptr_expr2 = calloc(1, sizeof(struct Expr));
		struct Expr *ptr_expr3 = calloc(1, sizeof(struct Expr));
		*ptr_expr1 = expr;
		*ptr_expr2 = true_branch;
		*ptr_expr3 = false_branch;

		struct Expr new_expr;
		new_expr.details = true_branch.details;
		new_expr.category = CONDITIONAL_EXPR;
		new_expr.ptr1 = ptr_expr1;
		new_expr.ptr2 = ptr_expr2;
		new_expr.ptr3 = ptr_expr3;
		return new_expr;
	}
	case BINARY_EXPR: {
		const struct Expr expr = typecheck_expression(ptr_ps, uexpr.ptr1);
		const struct Expr expr2 = typecheck_expression(ptr_ps, uexpr.ptr2);
		return typecheck_binary_expression(ptr_ps, &expr, &expr2,
		                                   uexpr.operator_);
	}
	}
	fprintf(stderr,
	        "****************************\n"
	        "* INTERNAL COMPILER ERROR @ %s\n"
	        "* Unexpected value in UntypedExprCategory: `uexpr.category` is `%d`\n"
	        "****************************\n",
	        __func__, uexpr.category);
	exit(EXIT_FAILURE);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3b8, %rsp            # imm = 0x3B8
movq %rdx, %rax
movq %rsi, %r14
movq %rdi, %r13
leaq -0xe0(%rbp), %r15
movl $0xa0, %edx
movq %r15, %rdi
movq %rax, %rsi
callq 0x1100
movl 0x4(%r15), %ecx
cmpq $0xc, %rcx
ja 0x5ca9
leaq 0x8f94(%rip), %rax      # 0xe4b4
movslq (%rax,%rcx,4), %rcx
addq %rax, %rcx
jmpq *%rcx
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x54d7
movq -0xd0(%rbp), %rdx
leaq -0x1e0(%rbp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x54d7
movl -0xe0(%rbp), %r8d
movq %r13, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %r12, %rcx
callq 0x62f6
jmp 0x5b98
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x54d7
movq -0x48(%rbp), %r12
movq %r15, %rdi
callq 0x81cb
testl %eax, %eax
je 0x5c14
movq %r13, -0x40(%rbp)
movq -0x2b0(%rbp), %rsi
movq 0x78(%r14), %rdi
movq %rsi, -0x30(%rbp)
callq 0x92a8
testq %rax, %rax
je 0x5c8c
movq %rax, -0x38(%rbp)
movq (%rax), %rax
movl (%rax), %r15d
movq 0x8(%rax), %rbx
xorl %r14d, %r14d
testl %r15d, %r15d
cmovlel %r14d, %r15d
cmpq %r14, %r15
je 0x5bed
movq (%rbx,%r14,8), %r13
movq 0x50(%r13), %rdi
movq %r12, %rsi
callq 0x10e0
testl %eax, %eax
je 0x5929
incq %r14
jmp 0x55de
movq %r13, %rdi
callq 0x81b0
movl -0xc0(%rbp), %eax
jmp 0x58fe
leaq -0xa8(%rbp), %rdx
movq -0x10(%rdx), %rbx
movq %r13, %rdi
movq %r14, %rsi
callq 0x5417
movq %rbx, 0xd0(%r13)
jmp 0x5b98
movq %r13, %rdi
callq 0x81b0
leaq -0x98(%rbp), %rsi
movq %r14, %rdi
callq 0x1e24
jmp 0x58fe
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %rdi
movq %r14, %rsi
callq 0x54d7
movq -0xd0(%rbp), %rdx
leaq -0x1e0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x54d7
movq -0xc8(%rbp), %rdx
leaq -0x3e0(%rbp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x54d7
movq %r15, %rdi
callq 0x5038
movq %r12, %rdi
callq 0x5038
cmpl $0x1, (%r12)
jne 0x59c8
movq %r13, %rbx
cmpl $0x9, -0x140(%rbp)
jne 0x5a08
cmpl $0x0, -0x118(%rbp)
jne 0x5a08
leaq -0x1e0(%rbp), %rdi
movl $0x12, 0xa0(%rdi)
leaq -0x3e0(%rbp), %rsi
jmp 0x59fe
movq -0xb8(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x5fcc
testq %rax, %rax
je 0x5c2d
movl $0x100, %edx            # imm = 0x100
movq %r13, %rdi
movq %rax, %rsi
callq 0x1100
jmp 0x5b98
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x54d7
movl (%r15), %eax
cmpl $0x3, %eax
je 0x575d
cmpl $0x1, %eax
jne 0x5c4a
movq -0x2d8(%rbp), %r15
cmpl $0x3, (%r15)
jne 0x5c4a
movq 0x8(%r15), %rdx
movq 0x20(%r15), %rax
movq %rax, -0x1d0(%rbp)
movups 0x10(%r15), %xmm0
movaps %xmm0, -0x1e0(%rbp)
cmpl $0x0, 0x28(%r15)
je 0x5b2a
movq -0x1d8(%rbp), %rax
movq -0x1d0(%rbp), %rsi
leaq -0x3e0(%rbp), %rcx
movq %rax, (%rcx)
movq %rsi, 0x8(%rcx)
jmp 0x5b2c
movl -0xe0(%rbp), %r15d
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %r12
movq %r12, %rdi
movq %r14, %rsi
callq 0x54d7
movq %r13, %rdi
movq %r14, %rsi
movq %r12, %rdx
movl %r15d, %ecx
callq 0x5199
jmp 0x5b98
movq -0xd8(%rbp), %rdx
leaq -0x2e0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x54d7
pushq $0x1
popq %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x10d0
movq %rax, %r12
movl $0x100, %edx            # imm = 0x100
movq %rax, %rdi
movq %r15, %rsi
callq 0x1100
movl -0xe0(%rbp), %edx
pushq $0xa
popq %rax
movq %rax, %rcx
movq %r13, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x50(%r13), %rdi
movq %rax, %rcx
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
xorl %eax, %eax
cmpl $0x32, %edx
sete %al
xorl $0xb, %eax
movl %eax, 0xa0(%r13)
movq %r12, 0xb0(%r13)
xorps %xmm0, %xmm0
movups %xmm0, 0xb8(%r13)
cmpl $0x1, (%r15)
jne 0x5b98
leaq -0x1e0(%rbp), %r15
leaq -0x2e0(%rbp), %rsi
movq %r15, %rdi
callq 0x85ad
movq %r14, %rdi
movq %r15, %rsi
callq 0x1e24
movl %eax, 0xf4(%r13)
jmp 0x5b98
movq -0xb8(%rbp), %r15
movq 0x18(%r14), %rdi
movq %r15, %rsi
callq 0x9304
testl %eax, %eax
je 0x5ac4
movq 0x18(%r14), %rdi
movq %r15, %rsi
callq 0x92a8
movq 0x8(%rax), %rsi
pushq $0xa
popq %rcx
leaq -0x1e0(%rbp), %rdi
rep  movsq (%rsi), %es:(%rdi)
cmpl $0x0, 0x28(%rax)
je 0x5b6f
movups 0x18(%rax), %xmm0
leaq -0x3e0(%rbp), %r12
movaps %xmm0, (%r12)
jmp 0x5b72
movq %r13, %rdi
callq 0x81b0
leaq -0x98(%rbp), %rsi
movq %r14, %rdi
callq 0x1f2e
movl %eax, 0xc8(%r13)
movl $0x9, 0xa0(%r13)
jmp 0x5b98
movq -0xb0(%rbp), %rsi
movq %r13, %rdi
callq 0x6271
jmp 0x5b98
pushq $0xa
popq %r15
leaq -0x1e0(%rbp), %rax
movq %r15, %rcx
movq %rax, %rdi
movq %r13, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x3e0(%rbp), %r12
movq %r12, %rdi
movq %rax, %rsi
callq 0x862d
movq %r15, %rcx
movq -0x40(%rbp), %r13
movq %r13, %rdi
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq 0x50(%r13), %rdi
movq %r15, %rcx
movq %r12, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movl (%rax,%r14,4), %ebx
pushq $0x1
popq %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x10d0
movq %rax, %r14
leaq -0x2e0(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
movq %rax, %rdi
callq 0x1100
movl $0x1a, 0xa0(%r13)
movl %ebx, 0xfc(%r13)
movq %r14, 0xb0(%r13)
xorps %xmm0, %xmm0
movups %xmm0, 0xb8(%r13)
jmp 0x5b98
movq %r13, %rbx
cmpl $0x1, -0x1e0(%rbp)
jne 0x5a08
cmpl $0x9, -0x340(%rbp)
jne 0x5a08
cmpl $0x0, -0x318(%rbp)
jne 0x5a08
leaq -0x3e0(%rbp), %rdi
movl $0x12, 0xa0(%rdi)
leaq -0x1e0(%rbp), %rsi
movl $0xa0, %edx
callq 0x1100
leaq 0x9010(%rip), %rcx      # 0xea1f
leaq -0x3e0(%rbp), %rsi
movq %r14, %rdi
movq %r15, %rdx
callq 0x4c73
pushq $0x1
popq %r12
movl $0x100, %esi            # imm = 0x100
movq %r12, %rdi
callq 0x10d0
movq %rax, %r14
movl $0x100, %esi            # imm = 0x100
movq %r12, %rdi
callq 0x10d0
movq %rax, %r13
movl $0x100, %esi            # imm = 0x100
movq %r12, %rdi
callq 0x10d0
movq %rax, %r12
leaq -0x2e0(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
movq %r14, %rdi
callq 0x1100
movl $0x100, %edx            # imm = 0x100
movq %r13, %rdi
movq %r15, %rsi
callq 0x1100
movl $0x100, %edx            # imm = 0x100
movq %r12, %rdi
leaq -0x3e0(%rbp), %rsi
callq 0x1100
movl $0xa0, %edx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1100
movl $0x5, 0xa0(%rbx)
movq %r14, 0xb0(%rbx)
movq %r13, 0xb8(%rbx)
movq %rbx, %r13
movq %r12, 0xc0(%rbx)
jmp 0x5b98
movq %r14, %rdi
movq %r15, %rsi
callq 0x5fcc
testq %rax, %rax
je 0x5bad
pushq $0x1
popq %rdi
movl $0xa0, %esi
callq 0x10d0
movq %rax, %r12
movl $0x3, 0x4(%rax)
movq %r15, 0x28(%rax)
leaq -0x2e0(%rbp), %r15
leaq -0xe0(%rbp), %rsi
movl $0xa0, %edx
movq %r15, %rdi
callq 0x1100
movl $0x7, 0x4(%r15)
movq %r12, 0x8(%r15)
movq %r13, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x54d7
jmp 0x5b98
xorl %ecx, %ecx
leaq -0xa8(%rbp), %r8
pushq $0x1
popq %r9
movq %r13, %rdi
movq %r14, %rsi
callq 0x5ccd
pushq $0x1
popq %rdi
movl $0x100, %esi            # imm = 0x100
callq 0x10d0
movq %rax, %r14
leaq -0x2e0(%rbp), %rsi
movl $0x100, %edx            # imm = 0x100
movq %rax, %rdi
callq 0x1100
movq %r14, 0xb0(%r13)
jmp 0x5b98
xorl %r12d, %r12d
leaq -0xa8(%rbp), %r8
leaq -0x1e0(%rbp), %rdx
movq %r13, %rdi
movq %r14, %rsi
movq %r12, %rcx
xorl %r9d, %r9d
callq 0x5ccd
movq %r15, 0xd0(%r13)
movq %r13, %rax
addq $0x3b8, %rsp            # imm = 0x3B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x10444(%rip), %rbx     # 0x15ff8
movq (%rbx), %rdi
leaq 0x8de9(%rip), %rsi      # 0xe9a7
xorl %r12d, %r12d
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
movq (%rbx), %rdi
leaq 0x8df8(%rip), %rsi      # 0xe9cd
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
leaq -0x1e0(%rbp), %rdi
callq 0x81b0
jmp 0x5b72
movq 0x10404(%rip), %rax     # 0x15ff8
movq (%rax), %rdi
leaq 0x8d0c(%rip), %rsi      # 0xe90a
movq %r12, %rdx
movq -0x30(%rbp), %rcx
xorl %eax, %eax
callq 0x10f0
pushq $0x1
popq %rdi
callq 0x1170
movq 0x103dd(%rip), %rax     # 0x15ff8
movq (%rax), %rcx
leaq 0x8c58(%rip), %rdi      # 0xe87d
pushq $0x49
popq %rsi
pushq $0x1
popq %rdx
jmp 0x5c85
movq 0x103c4(%rip), %rax     # 0x15ff8
movq (%rax), %rdi
leaq 0x8db2(%rip), %rsi      # 0xe9f0
movq %r15, %rdx
xorl %eax, %eax
callq 0x10f0
jmp 0x5c0c
movq 0x103a7(%rip), %r14     # 0x15ff8
movq (%r14), %rcx
leaq 0x8cdb(%rip), %rdi      # 0xe936
pushq $0x39
popq %rsi
pushq $0x1
popq %rbx
movq %rbx, %rdx
callq 0x1180
leaq -0x2e0(%rbp), %rdi
callq 0x827e
movq (%r14), %rcx
leaq 0x8cf1(%rip), %rdi      # 0xe970
pushq $0x36
popq %rsi
movq %rbx, %rdx
callq 0x1180
jmp 0x5c0c
movq 0x10365(%rip), %rax     # 0x15ff8
movq (%rax), %rdi
leaq 0x8c2a(%rip), %rsi      # 0xe8c7
movq -0x30(%rbp), %rcx
movq %rcx, %rdx
jmp 0x5c05
movq 0x10348(%rip), %rax     # 0x15ff8
movq (%rax), %rdi
leaq 0x8dbd(%rip), %rsi      # 0xea77
leaq 0x8e54(%rip), %rdx      # 0xeb15
xorl %eax, %eax
callq 0x10f0
jmp 0x5c0c