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

	switch (FE_EXPR_AST_NODE_GET_CONSTANT_TYPE(node_constexpr)) {
		case FE_TYPE_CHAR: {
			char str[128];
			snprintf(
				str, sizeof(str), "cast<char>(%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), "cast<int8>(%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), "cast<int16>(%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), "cast<int32>(%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), "cast<int64>(%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), "cast<uint8>(%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), "cast<uint16>(%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), "cast<uint32>(%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), "cast<uint64>(%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];
			float val = FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_FLOAT_VAL(node_constexpr);
			snprintf(
				str, sizeof(str), "cast<float>(%f)",
				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), "cast<double>(%lf)",
				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 rstr_string;
				rstr_init(&rstr_string);
				rstr_append_with_char(&rstr_string, '"');
				rstr_append_with_raw(&rstr_string, conststr->str, conststr->len);
				rstr_append_with_char(&rstr_string, '"');

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

				char str[1024];
				if (ptr_val == 0) {
					snprintf(
						str, sizeof(str), "cast<%s>(%s)",
						RSTR_CSTR(&target_type),
						RSTR_CSTR(&rstr_string)
					);
				} else {
					snprintf(
						str, sizeof(str), "cast<%s>(%s + %llu)",
						RSTR_CSTR(&target_type),
						RSTR_CSTR(&rstr_string),
						ptr_val
					);
				}

				rstr_append_with_cstr(rstr_val, str);

				rstr_free(&rstr_string);
				rstr_free(&target_type);
			} else {
				ResizableString target_type;
				rstr_init(&target_type);
				_ir_type(ctx, &target_type, FE_EXPR_AST_NODE_GET_TYPE_NODE(node_constexpr));

				char str[1024];
				snprintf(
					str, sizeof(str), "cast<%s>(%llu)",
					RSTR_CSTR(&target_type),
					FE_EXPR_AST_NODE_GET_CONSTEXPR_RESULT_POINTER_VAL(node_constexpr)
				);
				rstr_append_with_cstr(rstr_val, str);

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

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x428, %rsp            # imm = 0x428
testq %rdi, %rdi
je 0xceac
movq %rsi, %r14
cmpb $0x0, 0x70(%rsi)
je 0xcecb
movzbl 0x71(%r14), %eax
decl %eax
cmpl $0xf, %eax
ja 0xceea
movq %rdi, %rbx
leaq 0x315d3(%rip), %rcx     # 0x3e210
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movsbl 0x88(%r14), %ecx
leaq 0x31ea8(%rip), %rdx     # 0x3eafd
jmp 0xcddb
cmpb $0x1, 0x72(%r14)
jne 0xce0e
movq 0x88(%r14), %r15
leaq -0x38(%rbp), %r12
movq %r12, %rdi
callq 0x6e1c
pushq $0x22
popq %r13
movq %r12, %rdi
movl %r13d, %esi
callq 0x6f81
movq 0x78(%r14), %rsi
movl 0x80(%r14), %edx
movq %r12, %rdi
callq 0x700f
movq %r12, %rdi
movl %r13d, %esi
callq 0x6f81
leaq -0x48(%rbp), %r13
movq %r13, %rdi
callq 0x6e1c
movq 0x68(%r14), %rsi
movq %r13, %rdi
callq 0xbd8f
movq 0x8(%r13), %rcx
testq %rcx, %rcx
leaq 0x3324b(%rip), %rax     # 0x3ff16
cmoveq %rax, %rcx
movq 0x8(%r12), %r8
testq %r8, %r8
cmoveq %rax, %r8
testq %r15, %r15
je 0xce6c
leaq 0x31ed6(%rip), %rdx     # 0x3ebc1
leaq -0x450(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
movq %r15, %r9
xorl %eax, %eax
callq 0x3090
jmp 0xce86
cvtss2sd 0x88(%r14), %xmm0
leaq 0x31e7c(%rip), %rdx     # 0x3eb92
jmp 0xcd28
movsd 0x88(%r14), %xmm0
leaq 0x31e7a(%rip), %rdx     # 0x3eba2
leaq -0x450(%rbp), %r14
movl $0x80, %esi
movq %r14, %rdi
movb $0x1, %al
callq 0x3090
jmp 0xcdf1
movq 0x88(%r14), %rcx
leaq 0x31e2e(%rip), %rdx     # 0x3eb7f
jmp 0xcd61
movq 0x88(%r14), %rcx
leaq 0x31dda(%rip), %rdx     # 0x3eb3b
leaq -0x450(%rbp), %r14
movl $0x80, %esi
movq %r14, %rdi
xorl %eax, %eax
callq 0x3090
jmp 0xcdf1
movsbl 0x88(%r14), %ecx
leaq 0x31d84(%rip), %rdx     # 0x3eb0c
jmp 0xcddb
movzbl 0x88(%r14), %ecx
leaq 0x31db4(%rip), %rdx     # 0x3eb4d
jmp 0xcddb
movswl 0x88(%r14), %ecx
leaq 0x31d71(%rip), %rdx     # 0x3eb1b
jmp 0xcddb
movl 0x88(%r14), %ecx
leaq 0x31db4(%rip), %rdx     # 0x3eb6e
jmp 0xcddb
movl 0x88(%r14), %ecx
leaq 0x31d61(%rip), %rdx     # 0x3eb2b
jmp 0xcddb
movzwl 0x88(%r14), %ecx
leaq 0x31d82(%rip), %rdx     # 0x3eb5d
leaq -0x450(%rbp), %r14
movl $0x80, %esi
movq %r14, %rdi
xorl %eax, %eax
callq 0x3090
movq %rbx, %rdi
movq %r14, %rsi
callq 0x6e99
addq $0x428, %rsp            # imm = 0x428
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq -0x38(%rbp), %r15
movq %r15, %rdi
callq 0x6e1c
movq 0x68(%r14), %rsi
movq %r15, %rdi
callq 0xbd8f
movq 0x8(%r15), %rax
testq %rax, %rax
leaq 0x330e2(%rip), %rcx     # 0x3ff16
cmovneq %rax, %rcx
movq 0x88(%r14), %r8
leaq 0x31d8f(%rip), %rdx     # 0x3ebd5
leaq -0x450(%rbp), %r14
movl $0x400, %esi            # imm = 0x400
movq %r14, %rdi
xorl %eax, %eax
callq 0x3090
movq %rbx, %rdi
movq %r14, %rsi
callq 0x6e99
movq %r15, %rdi
jmp 0xcea2
leaq 0x31d41(%rip), %rdx     # 0x3ebb4
leaq -0x450(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
xorl %eax, %eax
callq 0x3090
leaq -0x450(%rbp), %rsi
movq %rbx, %rdi
callq 0x6e99
leaq -0x38(%rbp), %rdi
callq 0x72b9
leaq -0x48(%rbp), %rdi
callq 0x72b9
jmp 0xcdfc
leaq 0x31c41(%rip), %rdi     # 0x3eaf4
leaq 0x314ba(%rip), %rsi     # 0x3e374
leaq 0x31be6(%rip), %rcx     # 0x3eaa7
movl $0x2c3, %edx            # imm = 0x2C3
callq 0x30a0
leaq 0x31ba7(%rip), %rdi     # 0x3ea79
leaq 0x3149b(%rip), %rsi     # 0x3e374
leaq 0x31bc7(%rip), %rcx     # 0x3eaa7
movl $0x2c5, %edx            # imm = 0x2C5
callq 0x30a0
leaq 0x2f46f(%rip), %rdi     # 0x3c360
leaq 0x3147c(%rip), %rsi     # 0x3e374
leaq 0x31ba8(%rip), %rcx     # 0x3eaa7
movl $0x362, %edx            # imm = 0x362
callq 0x30a0