// File: /workspace/github_c_makefile_star2_O0/Ihsoh[P]ilang/compiler/frontend/irgen_llvmir.c
// Function: ir_constexpr
static void _ir_constexpr(
	IRGeneratorLlvmirContext *ctx,
	ResizableString *rstr_type,
	ResizableString *rstr_val,
	ParserASTNode *node_constexpr
) {
	assert(ctx);
	assert(rstr_val);
	assert(node_constexpr);
	assert(FE_EXPR_AST_NODE_GET_CONSTANT(node_constexpr));

	if (rstr_type != NULL) {
		_ir_type(ctx, rstr_type, FE_EXPR_AST_NODE_GET_TYPE_NODE(node_constexpr));
	}

	switch (FE_EXPR_AST_NODE_GET_CONSTANT_TYPE(node_constexpr)) {
		case FE_TYPE_CHAR: {
			char str[128];
			snprintf(
				str, sizeof(str), "%d",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_CHAR_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_INT8: {
			char str[128];
			snprintf(
				str, sizeof(str), "%d",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_INT8_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_INT16: {
			char str[128];
			snprintf(
				str, sizeof(str), "%d",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_INT16_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_INT32: {
			char str[128];
			snprintf(
				str, sizeof(str), "%d",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_INT32_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_INT64: {
			char str[128];
			snprintf(
				str, sizeof(str), "%lld",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_INT64_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_UINT8: {
			char str[128];
			snprintf(
				str, sizeof(str), "%u",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_UINT8_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_UINT16: {
			char str[128];
			snprintf(
				str, sizeof(str), "%u",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_UINT16_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_UINT32: {
			char str[128];
			snprintf(
				str, sizeof(str), "%u",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_UINT32_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_UINT64: {
			char str[128];
			snprintf(
				str, sizeof(str), "%llu",
				FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_UINT64_VAL(node_constexpr)
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_FLOAT: {
			char str[128];
			double val = FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_FLOAT_VAL(node_constexpr);
			snprintf(
				str, sizeof(str), "0x%llX",
				*(uint64_t *)&val
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_DOUBLE: {
			char str[128];
			double val = FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_DOUBLE_VAL(node_constexpr);
			snprintf(
				str, sizeof(str), "0x%llX",
				*(uint64_t *)&val
			);
			rstr_append_with_cstr(rstr_val, str);
			break;
		}
		case FE_TYPE_POINTER: {
			if (FE_EXPR_AST_NODE_GET_HAS_CONSTSTR(node_constexpr)) {
				FeParserConstexprString *conststr = FE_EXPR_AST_NODE_GET_CONSTSTR(node_constexpr);
				uint64_t ptr_val = FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_POINTER_VAL(node_constexpr);

				ResizableString conststr_name;
				rstr_init(&conststr_name);

				int len = _new_string(ctx, &conststr_name, conststr->str, conststr->len);

				ResizableString target_type;
				rstr_init(&target_type);

				_ir_type(ctx, &target_type, FE_EXPR_AST_NODE_GET_TYPE_NODE(node_constexpr));

				char *offset_type = "";
				if (ctx->psrctx->arch == FE_ARCH_32) {
					offset_type = "i32";
				} else if (ctx->psrctx->arch == FE_ARCH_64) {
					offset_type = "i64";
				} else {
					assert(0);
				}

				if (ptr_val == 0) {
					rstr_appendf(
						rstr_val,
						"bitcast (i8* getelementptr inbounds ([%zu x i8], [%zu x i8]* %s, i32 0, %s 0) to %s)",
						len,
						len,
						RSTR_CSTR(&conststr_name),
						offset_type,
						RSTR_CSTR(&target_type)
					);
				} else {
					rstr_appendf(
						rstr_val,
						"bitcast (i8* getelementptr inbounds ([%zu x i8], [%zu x i8]* %s, i32 0, %s %u) to %s)",
						len,
						len,
						RSTR_CSTR(&conststr_name),
						offset_type,
						ptr_val,
						RSTR_CSTR(&target_type)
					);
				}

				rstr_free(&conststr_name);
				rstr_free(&target_type);
			} else {
				char *source_type = "";
				if (ctx->psrctx->arch == FE_ARCH_32) {
					source_type = "i32";
				} else if (ctx->psrctx->arch == FE_ARCH_64) {
					source_type = "i64";
				} else {
					assert(0);
				}

				ResizableString target_type;
				rstr_init(&target_type);
				_ir_type(ctx, &target_type, FE_EXPR_AST_NODE_GET_TYPE_NODE(node_constexpr));

				char str[128];
				snprintf(
					str, sizeof(str), "inttoptr (%s %llu to %s)",
					source_type,
					FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_POINTER_VAL(node_constexpr),
					RSTR_CSTR(&target_type)
				);
				rstr_append_with_cstr(rstr_val, str);

				rstr_free(&target_type);
			}
			break;
		}
		default: {
			assert(0);
		}
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x730, %rsp            # imm = 0x730
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x2ca84
jmp 0x2caa3
leaq 0x4facb(%rip), %rdi     # 0x7c556
leaq 0x4b63e(%rip), %rsi     # 0x780d0
movl $0x326, %edx            # imm = 0x326
leaq 0x4ba94(%rip), %rcx     # 0x78532
callq 0x30a0
cmpq $0x0, -0x18(%rbp)
je 0x2caac
jmp 0x2cacb
leaq 0x48070(%rip), %rdi     # 0x74b23
leaq 0x4b616(%rip), %rsi     # 0x780d0
movl $0x327, %edx            # imm = 0x327
leaq 0x4ba6c(%rip), %rcx     # 0x78532
callq 0x30a0
cmpq $0x0, -0x20(%rbp)
je 0x2cad4
jmp 0x2caf3
leaq 0x47fbe(%rip), %rdi     # 0x74a99
leaq 0x4b5ee(%rip), %rsi     # 0x780d0
movl $0x328, %edx            # imm = 0x328
leaq 0x4ba44(%rip), %rcx     # 0x78532
callq 0x30a0
movq -0x20(%rbp), %rax
testb $0x1, 0x70(%rax)
je 0x2caff
jmp 0x2cb1e
leaq 0x47fa2(%rip), %rdi     # 0x74aa8
leaq 0x4b5c3(%rip), %rsi     # 0x780d0
movl $0x329, %edx            # imm = 0x329
leaq 0x4ba19(%rip), %rcx     # 0x78532
callq 0x30a0
cmpq $0x0, -0x10(%rbp)
je 0x2cb3a
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x20(%rbp), %rax
movq 0x68(%rax), %rdx
callq 0x299e0
movq -0x20(%rbp), %rax
movzbl 0x71(%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x698(%rbp)
subl $0xf, %eax
ja 0x2d210
movq -0x698(%rbp), %rax
leaq 0x4b464(%rip), %rcx     # 0x77fc8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0xa0(%rbp), %rdi
movq -0x20(%rbp), %rax
movsbl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4b7c4(%rip), %rdx     # 0x7834f
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x120(%rbp), %rdi
movq -0x20(%rbp), %rax
movsbl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4b78a(%rip), %rdx     # 0x7834f
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x1a0(%rbp), %rdi
movq -0x20(%rbp), %rax
movswl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4b750(%rip), %rdx     # 0x7834f
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x220(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4b717(%rip), %rdx     # 0x7834f
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x2a0(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x88(%rax), %rcx
movl $0x80, %esi
leaq 0x4a4ff(%rip), %rdx     # 0x77171
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x2a0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x320(%rbp), %rdi
movq -0x20(%rbp), %rax
movzbl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4a4ca(%rip), %rdx     # 0x77176
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x3a0(%rbp), %rdi
movq -0x20(%rbp), %rax
movzwl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4a490(%rip), %rdx     # 0x77176
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x3a0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x420(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x88(%rax), %ecx
movl $0x80, %esi
leaq 0x4a457(%rip), %rdx     # 0x77176
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
leaq -0x4a0(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x88(%rax), %rcx
movl $0x80, %esi
leaq 0x4a420(%rip), %rdx     # 0x77179
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x4a0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
movq -0x20(%rbp), %rax
movss 0x88(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x528(%rbp)
leaq -0x520(%rbp), %rdi
movq -0x528(%rbp), %rcx
movl $0x80, %esi
leaq 0x4b7f1(%rip), %rdx     # 0x78598
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x520(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
movq -0x20(%rbp), %rax
movsd 0x88(%rax), %xmm0
movsd %xmm0, -0x5b8(%rbp)
leaq -0x5b0(%rbp), %rdi
movq -0x5b8(%rbp), %rcx
movl $0x80, %esi
leaq 0x4b7a7(%rip), %rdx     # 0x78598
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x5b0(%rbp), %rsi
callq 0x8d70
jmp 0x2d22f
movq -0x20(%rbp), %rax
testb $0x1, 0x72(%rax)
je 0x2d0e0
movq -0x20(%rbp), %rax
addq $0x60, %rax
addq $0x18, %rax
movq %rax, -0x5c0(%rbp)
movq -0x20(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0x5c8(%rbp)
leaq -0x5d8(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x5c0(%rbp), %rax
movq (%rax), %rdx
movq -0x5c0(%rbp), %rax
movq 0x8(%rax), %rcx
leaq -0x5d8(%rbp), %rsi
callq 0x2d240
movl %eax, -0x5dc(%rbp)
leaq -0x5f0(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x68(%rax), %rdx
leaq -0x5f0(%rbp), %rsi
callq 0x299e0
leaq 0x4aa13(%rip), %rax     # 0x778b5
movq %rax, -0x5f8(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x1, 0x30(%rax)
jne 0x2cec6
leaq 0x4b51f(%rip), %rax     # 0x783dc
movq %rax, -0x5f8(%rbp)
jmp 0x2cf04
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x2, 0x30(%rax)
jne 0x2cee3
leaq 0x4b506(%rip), %rax     # 0x783e0
movq %rax, -0x5f8(%rbp)
jmp 0x2cf02
leaq 0x45571(%rip), %rdi     # 0x7245b
leaq 0x4b1df(%rip), %rsi     # 0x780d0
movl $0x3aa, %edx            # imm = 0x3AA
leaq 0x4b635(%rip), %rcx     # 0x78532
callq 0x30a0
jmp 0x2cf04
cmpq $0x0, -0x5c8(%rbp)
jne 0x2cfe0
movq -0x18(%rbp), %rax
movq %rax, -0x6a8(%rbp)
movl -0x5dc(%rbp), %eax
movl %eax, -0x6a0(%rbp)
movl -0x5dc(%rbp), %eax
movl %eax, -0x69c(%rbp)
cmpq $0x0, -0x5d0(%rbp)
jne 0x2cf4f
leaq 0x4a96f(%rip), %rax     # 0x778b5
movq %rax, -0x6b0(%rbp)
jmp 0x2cf5d
movq -0x5d0(%rbp), %rax
movq %rax, -0x6b0(%rbp)
movq -0x6b0(%rbp), %rax
movq %rax, -0x6c0(%rbp)
movq -0x5f8(%rbp), %rax
movq %rax, -0x6b8(%rbp)
cmpq $0x0, -0x5e8(%rbp)
jne 0x2cf93
leaq 0x4a92b(%rip), %rax     # 0x778b5
movq %rax, -0x6c8(%rbp)
jmp 0x2cfa1
movq -0x5e8(%rbp), %rax
movq %rax, -0x6c8(%rbp)
movq -0x6b8(%rbp), %r9
movq -0x6c0(%rbp), %r8
movl -0x69c(%rbp), %ecx
movl -0x6a0(%rbp), %edx
movq -0x6a8(%rbp), %rdi
movq -0x6c8(%rbp), %rax
leaq 0x4b5cf(%rip), %rsi     # 0x7859f
movq %rax, (%rsp)
movb $0x0, %al
callq 0x94d0
jmp 0x2d0c3
movq -0x18(%rbp), %rax
movq %rax, -0x6d8(%rbp)
movl -0x5dc(%rbp), %eax
movl %eax, -0x6d0(%rbp)
movl -0x5dc(%rbp), %eax
movl %eax, -0x6cc(%rbp)
cmpq $0x0, -0x5d0(%rbp)
jne 0x2d01d
leaq 0x4a8a1(%rip), %rax     # 0x778b5
movq %rax, -0x6e0(%rbp)
jmp 0x2d02b
movq -0x5d0(%rbp), %rax
movq %rax, -0x6e0(%rbp)
movq -0x6e0(%rbp), %rax
movq %rax, -0x6f8(%rbp)
movq -0x5f8(%rbp), %rax
movq %rax, -0x6f0(%rbp)
movq -0x5c8(%rbp), %rax
movq %rax, -0x6e8(%rbp)
cmpq $0x0, -0x5e8(%rbp)
jne 0x2d06f
leaq 0x4a84f(%rip), %rax     # 0x778b5
movq %rax, -0x700(%rbp)
jmp 0x2d07d
movq -0x5e8(%rbp), %rax
movq %rax, -0x700(%rbp)
movq -0x6e8(%rbp), %r10
movq -0x6f0(%rbp), %r9
movq -0x6f8(%rbp), %r8
movl -0x6cc(%rbp), %ecx
movl -0x6d0(%rbp), %edx
movq -0x6d8(%rbp), %rdi
movq -0x700(%rbp), %rax
leaq 0x4b541(%rip), %rsi     # 0x785f4
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x94d0
leaq -0x5d8(%rbp), %rdi
callq 0x9310
leaq -0x5f0(%rbp), %rdi
callq 0x9310
jmp 0x2d20e
leaq 0x4a7ce(%rip), %rax     # 0x778b5
movq %rax, -0x600(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x1, 0x30(%rax)
jne 0x2d10b
leaq 0x4b2da(%rip), %rax     # 0x783dc
movq %rax, -0x600(%rbp)
jmp 0x2d149
movq -0x8(%rbp), %rax
movq (%rax), %rax
cmpl $0x2, 0x30(%rax)
jne 0x2d128
leaq 0x4b2c1(%rip), %rax     # 0x783e0
movq %rax, -0x600(%rbp)
jmp 0x2d147
leaq 0x4532c(%rip), %rdi     # 0x7245b
leaq 0x4af9a(%rip), %rsi     # 0x780d0
movl $0x3cd, %edx            # imm = 0x3CD
leaq 0x4b3f0(%rip), %rcx     # 0x78532
callq 0x30a0
jmp 0x2d149
leaq -0x610(%rbp), %rdi
callq 0x8c90
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x68(%rax), %rdx
leaq -0x610(%rbp), %rsi
callq 0x299e0
leaq -0x690(%rbp), %rax
movq %rax, -0x718(%rbp)
movq -0x600(%rbp), %rax
movq %rax, -0x710(%rbp)
movq -0x20(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0x708(%rbp)
cmpq $0x0, -0x608(%rbp)
jne 0x2d1b5
leaq 0x4a709(%rip), %rax     # 0x778b5
movq %rax, -0x720(%rbp)
jmp 0x2d1c3
movq -0x608(%rbp), %rax
movq %rax, -0x720(%rbp)
movq -0x708(%rbp), %r8
movq -0x710(%rbp), %rcx
movq -0x718(%rbp), %rdi
movq -0x720(%rbp), %r9
movl $0x80, %esi
leaq 0x4b45f(%rip), %rdx     # 0x7864a
movb $0x0, %al
callq 0x3090
movq -0x18(%rbp), %rdi
leaq -0x690(%rbp), %rsi
callq 0x8d70
leaq -0x610(%rbp), %rdi
callq 0x9310
jmp 0x2d22f
leaq 0x45244(%rip), %rdi     # 0x7245b
leaq 0x4aeb2(%rip), %rsi     # 0x780d0
movl $0x3e2, %edx            # imm = 0x3E2
leaq 0x4b308(%rip), %rcx     # 0x78532
callq 0x30a0
addq $0x730, %rsp            # imm = 0x730
popq %rbp
retq
nopl (%rax,%rax)