aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
authorVexu <git@vexu.eu>2020-03-10 22:33:32 +0200
committerVexu <git@vexu.eu>2020-03-10 22:33:32 +0200
commit8dc188ebe06b5b78dcead521561858fc27e25204 (patch)
treed5c05dbe81a0afc0a738dec42f2809a569a3f248 /src/codegen.cpp
parent675f01f1768aa08c307640b53e8a5240fa190fab (diff)
downloadzig-8dc188ebe06b5b78dcead521561858fc27e25204.tar.gz
zig-8dc188ebe06b5b78dcead521561858fc27e25204.zip
support atomic operations with bools
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 22cb975205..7238d5041b 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -5224,6 +5224,15 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
LLVMValueRef cmp_val = ir_llvm_value(g, instruction->cmp_value);
LLVMValueRef new_val = ir_llvm_value(g, instruction->new_value);
+ ZigType *operand_type = instruction->new_value->value->type;
+ if (operand_type->id == ZigTypeIdBool) {
+ // treat bool as u8
+ ptr_val = LLVMBuildBitCast(g->builder, ptr_val,
+ LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");
+ cmp_val = LLVMConstZExt(cmp_val, g->builtin_types.entry_u8->llvm_type);
+ new_val = LLVMConstZExt(new_val, g->builtin_types.entry_u8->llvm_type);
+ }
+
LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order);
LLVMAtomicOrdering failure_order = to_LLVMAtomicOrdering(instruction->failure_order);
@@ -5236,6 +5245,9 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
if (!handle_is_ptr(g, optional_type)) {
LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
+ if (operand_type->id == ZigTypeIdBool) {
+ payload_val = LLVMBuildTrunc(g->builder, payload_val, g->builtin_types.entry_bool->llvm_type, "");
+ }
LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, "");
return LLVMBuildSelect(g->builder, success_bit, LLVMConstNull(get_llvm_type(g, child_type)), payload_val, "");
}
@@ -5250,6 +5262,9 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I
ir_assert(type_has_bits(g, child_type), &instruction->base);
LLVMValueRef payload_val = LLVMBuildExtractValue(g->builder, result_val, 0, "");
+ if (operand_type->id == ZigTypeIdBool) {
+ payload_val = LLVMBuildTrunc(g->builder, payload_val, g->builtin_types.entry_bool->llvm_type, "");
+ }
LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, "");
gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val);
@@ -5827,6 +5842,16 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef operand = ir_llvm_value(g, instruction->operand);
+ if (operand_type->id == ZigTypeIdBool) {
+ // treat bool as u8
+ LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr,
+ LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");
+ LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, g->builtin_types.entry_u8->llvm_type, "");
+ LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering,
+ g->is_single_threaded);
+ return LLVMBuildTrunc(g->builder, uncasted_result, g->builtin_types.entry_bool->llvm_type, "");
+ }
+
if (get_codegen_ptr_type_bail(g, operand_type) == nullptr) {
return ZigLLVMBuildAtomicRMW(g->builder, op, ptr, operand, ordering, g->is_single_threaded);
}
@@ -5845,6 +5870,16 @@ static LLVMValueRef ir_render_atomic_load(CodeGen *g, IrExecutableGen *executabl
{
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
+
+ ZigType *operand_type = instruction->ptr->value->type->data.pointer.child_type;
+ if (operand_type->id == ZigTypeIdBool) {
+ // treat bool as u8
+ ptr = LLVMBuildBitCast(g->builder, ptr,
+ LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");
+ LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
+ LLVMSetOrdering(load_inst, ordering);
+ return LLVMBuildTrunc(g->builder, load_inst, g->builtin_types.entry_bool->llvm_type, "");
+ }
LLVMValueRef load_inst = gen_load(g, ptr, instruction->ptr->value->type, "");
LLVMSetOrdering(load_inst, ordering);
return load_inst;
@@ -5856,6 +5891,14 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab
LLVMAtomicOrdering ordering = to_LLVMAtomicOrdering(instruction->ordering);
LLVMValueRef ptr = ir_llvm_value(g, instruction->ptr);
LLVMValueRef value = ir_llvm_value(g, instruction->value);
+
+ ZigType *operand_type = instruction->value->value->type;
+ if (operand_type->id == ZigTypeIdBool) {
+ // treat bool as u8
+ ptr = LLVMBuildBitCast(g->builder, ptr,
+ LLVMPointerType(g->builtin_types.entry_u8->llvm_type, 0), "");
+ value = LLVMConstZExt(value, g->builtin_types.entry_u8->llvm_type);
+ }
LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type);
LLVMSetOrdering(store_inst, ordering);
return nullptr;