authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-12 17:13:33+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2019-11-12 17:13:33+02:00
log7e5b234b8b3a7e675a7b11eebcdaf504f2686749
treeb79ad9183c18f149c724ea7df9726ab85fbe8cce
parent45d2fd9b9d86c4a5751612f62aa324d635976bf8
signaturelock-open Commit is signed but in an unrecognized format.

support atomic operations with enums


2 files changed, 37 insertions(+), 1 deletions(-)

src/ir.cpp+21-1
...@@ -25618,9 +25618,29 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op...@@ -25618,9 +25618,29 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
25618 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));25618 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count));
25619 return ira->codegen->builtin_types.entry_invalid;25619 return ira->codegen->builtin_types.entry_invalid;
25620 }25620 }
25621 } else if (operand_type->id == ZigTypeIdEnum) {
25622 ZigType *int_type = operand_type->data.enumeration.tag_int_type;
25623 if (int_type->data.integral.bit_count < 8) {
25624 ir_add_error(ira, op,
25625 buf_sprintf("expected enum tag type 8 bits or larger, found %" PRIu32 "-bit tag type",
25626 int_type->data.integral.bit_count));
25627 return ira->codegen->builtin_types.entry_invalid;
25628 }
25629 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
25630 if (int_type->data.integral.bit_count > max_atomic_bits) {
25631 ir_add_error(ira, op,
25632 buf_sprintf("expected %" PRIu32 "-bit enum tag type or smaller, found %" PRIu32 "-bit tag type",
25633 max_atomic_bits, int_type->data.integral.bit_count));
25634 return ira->codegen->builtin_types.entry_invalid;
25635 }
25636 if (!is_power_of_2(int_type->data.integral.bit_count)) {
25637 ir_add_error(ira, op,
25638 buf_sprintf("%" PRIu32 "-bit enum tag type is not a power of 2", int_type->data.integral.bit_count));
25639 return ira->codegen->builtin_types.entry_invalid;
25640 }
25621 } else if (get_codegen_ptr_type(operand_type) == nullptr) {25641 } else if (get_codegen_ptr_type(operand_type) == nullptr) {
25622 ir_add_error(ira, op,25642 ir_add_error(ira, op,
25623 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name)));25643 buf_sprintf("expected integer, enum or pointer type, found '%s'", buf_ptr(&operand_type->name)));
25624 return ira->codegen->builtin_types.entry_invalid;25644 return ira->codegen->builtin_types.entry_invalid;
25625 }25645 }
2562625646
test/stage1/behavior/atomics.zig+16
...@@ -107,3 +107,19 @@ test "cmpxchg on a global variable" {...@@ -107,3 +107,19 @@ test "cmpxchg on a global variable" {
107 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);107 _ = @cmpxchgWeak(u32, &a_global_variable, 1234, 42, .Acquire, .Monotonic);
108 expectEqual(@as(u32, 42), a_global_variable);108 expectEqual(@as(u32, 42), a_global_variable);
109}109}
110
111test "atomic load and rmw with enum" {
112 const Value = enum(u8) {
113 a,
114 b,
115 c,
116 };
117 var x = Value.a;
118
119 expect(@atomicLoad(Value, &x, .SeqCst) != .b);
120
121 _ = @atomicRmw(Value, &x, .Xchg, .c, .SeqCst);
122 expect(@atomicLoad(Value, &x, .SeqCst) == .c);
123 expect(@atomicLoad(Value, &x, .SeqCst) != .a);
124 expect(@atomicLoad(Value, &x, .SeqCst) != .b);
125}