diff --git a/doc/langref.html.in b/doc/langref.html.in index 3a3eaf708c3c82f9843be7c06a249529de909cb0..9a286cb0638b9df9d9a970d75579d6e4523e38e7 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7823,7 +7823,7 @@ Environments: coreclr opencl
- The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating sytsem
+ The Zig Standard Library ({#syntax#}@import("std"){#endsyntax#}) has architecture, environment, and operating system
abstractions, and thus takes additional work to support more platforms.
Not all standard library code requires operating system abstractions, however,
so things such as generic data structures work an all above platforms.
diff --git a/src/all_types.hpp b/src/all_types.hpp
index fe36eb3a5d3ae5fa345c80a63ffc65371d9be7f1..29598672cd4b58458d11c77b88b88ac1cfcf251e 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -2198,6 +2198,7 @@ enum IrInstructionId {
IrInstructionIdPtrCastSrc,
IrInstructionIdPtrCastGen,
IrInstructionIdBitCast,
+ IrInstructionIdBitCastGen,
IrInstructionIdWidenOrShorten,
IrInstructionIdIntToPtr,
IrInstructionIdPtrToInt,
@@ -3055,6 +3056,13 @@ struct IrInstructionBitCast {
IrInstruction *value;
};
+struct IrInstructionBitCastGen {
+ IrInstruction base;
+
+ IrInstruction *operand;
+ LLVMValueRef tmp_ptr;
+};
+
struct IrInstructionWidenOrShorten {
IrInstruction base;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 6c9e8ccc4bae79bcaaf9f8d7b5e3394631d53ffb..c43611e8af8206d4fbc04dcd9279268899cfc2c9 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -3073,14 +3073,32 @@ static LLVMValueRef ir_render_ptr_cast(CodeGen *g, IrExecutable *executable,
}
static LLVMValueRef ir_render_bit_cast(CodeGen *g, IrExecutable *executable,
- IrInstructionBitCast *instruction)
+ IrInstructionBitCastGen *instruction)
{
ZigType *wanted_type = instruction->base.value.type;
- LLVMValueRef value = ir_llvm_value(g, instruction->value);
- // We either bitcast the value directly or bitcast the pointer which does a pointer cast
- LLVMTypeRef wanted_type_ref = handle_is_ptr(wanted_type) ?
- LLVMPointerType(wanted_type->type_ref, 0) : wanted_type->type_ref;
- return LLVMBuildBitCast(g->builder, value, wanted_type_ref, "");
+ ZigType *actual_type = instruction->operand->value.type;
+ LLVMValueRef value = ir_llvm_value(g, instruction->operand);
+
+ bool wanted_is_ptr = handle_is_ptr(wanted_type);
+ bool actual_is_ptr = handle_is_ptr(actual_type);
+ if (wanted_is_ptr == actual_is_ptr) {
+ // We either bitcast the value directly or bitcast the pointer which does a pointer cast
+ LLVMTypeRef wanted_type_ref = wanted_is_ptr ?
+ LLVMPointerType(wanted_type->type_ref, 0) : wanted_type->type_ref;
+ return LLVMBuildBitCast(g->builder, value, wanted_type_ref, "");
+ } else if (actual_is_ptr) {
+ LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(wanted_type->type_ref, 0);
+ LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, "");
+ uint32_t alignment = get_abi_alignment(g, actual_type);
+ return gen_load_untyped(g, bitcasted_ptr, alignment, false, "");
+ } else {
+ assert(instruction->tmp_ptr != nullptr);
+ LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(actual_type->type_ref, 0);
+ LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, instruction->tmp_ptr, wanted_ptr_type_ref, "");
+ uint32_t alignment = get_abi_alignment(g, wanted_type);
+ gen_store_untyped(g, value, bitcasted_ptr, alignment, false);
+ return instruction->tmp_ptr;
+ }
}
static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executable,
@@ -5469,6 +5487,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
case IrInstructionIdPtrCastSrc:
case IrInstructionIdCmpxchgSrc:
case IrInstructionIdLoadPtr:
+ case IrInstructionIdBitCast:
zig_unreachable();
case IrInstructionIdDeclVarGen:
@@ -5565,8 +5584,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_union_init(g, executable, (IrInstructionUnionInit *)instruction);
case IrInstructionIdPtrCastGen:
return ir_render_ptr_cast(g, executable, (IrInstructionPtrCastGen *)instruction);
- case IrInstructionIdBitCast:
- return ir_render_bit_cast(g, executable, (IrInstructionBitCast *)instruction);
+ case IrInstructionIdBitCastGen:
+ return ir_render_bit_cast(g, executable, (IrInstructionBitCastGen *)instruction);
case IrInstructionIdWidenOrShorten:
return ir_render_widen_or_shorten(g, executable, (IrInstructionWidenOrShorten *)instruction);
case IrInstructionIdPtrToInt:
@@ -6764,6 +6783,9 @@ static void do_code_gen(CodeGen *g) {
} else if (instruction->id == IrInstructionIdLoadPtrGen) {
IrInstructionLoadPtrGen *load_ptr_inst = (IrInstructionLoadPtrGen *)instruction;
slot = &load_ptr_inst->tmp_ptr;
+ } else if (instruction->id == IrInstructionIdBitCastGen) {
+ IrInstructionBitCastGen *bit_cast_inst = (IrInstructionBitCastGen *)instruction;
+ slot = &bit_cast_inst->tmp_ptr;
} else if (instruction->id == IrInstructionIdVectorToArray) {
IrInstructionVectorToArray *vector_to_array_instruction = (IrInstructionVectorToArray *)instruction;
alignment_bytes = get_abi_alignment(g, vector_to_array_instruction->vector->value.type);
diff --git a/src/ir.cpp b/src/ir.cpp
index 5fae81f0ce6c1bc31188adff9374b8a3f7877241..36f11cb10899888de3d2a652778bf36548c9ca8a 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -744,6 +744,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) {
return IrInstructionIdBitCast;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCastGen *) {
+ return IrInstructionIdBitCastGen;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) {
return IrInstructionIdWidenOrShorten;
}
@@ -2317,12 +2321,25 @@ static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *s
instruction->dest_type = dest_type;
instruction->value = value;
- if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block);
+ ir_ref_instruction(dest_type, irb->current_basic_block);
ir_ref_instruction(value, irb->current_basic_block);
return &instruction->base;
}
+static IrInstruction *ir_build_bit_cast_gen(IrAnalyze *ira, IrInstruction *source_instruction,
+ IrInstruction *operand, ZigType *ty)
+{
+ IrInstructionBitCastGen *instruction = ir_build_instruction