| author | |
| committer | |
| log | ec906a97712b329694e8f2e1a35b50b75d052642 |
| tree | e0b5234faa2cbc58bd7a54d8d77f797fa47c5bc1 |
| parent | 1f66435a6b0c5ccf6e4e96df0ed96732480ab4db |
| signature |
3 files changed, 17 insertions(+), 43 deletions(-)
doc/langref.html.in+10-35| ... | @@ -6728,17 +6728,8 @@ async fn func(y: *i32) void { | ... | @@ -6728,17 +6728,8 @@ async fn func(y: *i32) void { |
| 6728 | This builtin function atomically dereferences a pointer and returns the value. | 6728 | This builtin function atomically dereferences a pointer and returns the value. |
| 6729 | </p> | 6729 | </p> |
| 6730 | <p> | 6730 | <p> |
| 6731 | {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float, | 6731 | {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, |
| 6732 | an integer whose bit count meets these requirements: | 6732 | an integer or an enum. |
| 6733 | </p> | ||
| 6734 | <ul> | ||
| 6735 | <li>At least 8</li> | ||
| 6736 | <li>At most the same as usize</li> | ||
| 6737 | <li>Power of 2</li> | ||
| 6738 | </ul> or an enum with a valid integer tag type. | ||
| 6739 | <p> | ||
| 6740 | TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe | ||
| 6741 | we can remove this restriction | ||
| 6742 | </p> | 6733 | </p> |
| 6743 | {#header_close#} | 6734 | {#header_close#} |
| 6744 | {#header_open|@atomicRmw#} | 6735 | {#header_open|@atomicRmw#} |
| ... | @@ -6747,17 +6738,8 @@ async fn func(y: *i32) void { | ... | @@ -6747,17 +6738,8 @@ async fn func(y: *i32) void { |
| 6747 | This builtin function atomically modifies memory and then returns the previous value. | 6738 | This builtin function atomically modifies memory and then returns the previous value. |
| 6748 | </p> | 6739 | </p> |
| 6749 | <p> | 6740 | <p> |
| 6750 | {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, | 6741 | {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, |
| 6751 | or an integer whose bit count meets these requirements: | 6742 | an integer or an enum. |
| 6752 | </p> | ||
| 6753 | <ul> | ||
| 6754 | <li>At least 8</li> | ||
| 6755 | <li>At most the same as usize</li> | ||
| 6756 | <li>Power of 2</li> | ||
| 6757 | </ul> | ||
| 6758 | <p> | ||
| 6759 | TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe | ||
| 6760 | we can remove this restriction | ||
| 6761 | </p> | 6743 | </p> |
| 6762 | <p> | 6744 | <p> |
| 6763 | Supported operations: | 6745 | Supported operations: |
| ... | @@ -6782,17 +6764,8 @@ async fn func(y: *i32) void { | ... | @@ -6782,17 +6764,8 @@ async fn func(y: *i32) void { |
| 6782 | This builtin function atomically stores a value. | 6764 | This builtin function atomically stores a value. |
| 6783 | </p> | 6765 | </p> |
| 6784 | <p> | 6766 | <p> |
| 6785 | {#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float, | 6767 | {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, |
| 6786 | an integer whose bit count meets these requirements: | 6768 | an integer or an enum. |
| 6787 | </p> | ||
| 6788 | <ul> | ||
| 6789 | <li>At least 8</li> | ||
| 6790 | <li>At most the same as usize</li> | ||
| 6791 | <li>Power of 2</li> | ||
| 6792 | </ul> or an enum with a valid integer tag type. | ||
| 6793 | <p> | ||
| 6794 | TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe | ||
| 6795 | we can remove this restriction | ||
| 6796 | </p> | 6769 | </p> |
| 6797 | {#header_close#} | 6770 | {#header_close#} |
| 6798 | {#header_open|@bitCast#} | 6771 | {#header_open|@bitCast#} |
| ... | @@ -7108,7 +7081,8 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_v | ... | @@ -7108,7 +7081,8 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_v |
| 7108 | more efficiently in machine instructions. | 7081 | more efficiently in machine instructions. |
| 7109 | </p> | 7082 | </p> |
| 7110 | <p> | 7083 | <p> |
| 7111 | {#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}. | 7084 | {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, |
| 7085 | an integer or an enum. | ||
| 7112 | </p> | 7086 | </p> |
| 7113 | <p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> | 7087 | <p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> |
| 7114 | {#see_also|Compile Variables|cmpxchgWeak#} | 7088 | {#see_also|Compile Variables|cmpxchgWeak#} |
| ... | @@ -7136,7 +7110,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -7136,7 +7110,8 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 7136 | However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}. | 7110 | However if you need a stronger guarantee, use {#link|@cmpxchgStrong#}. |
| 7137 | </p> | 7111 | </p> |
| 7138 | <p> | 7112 | <p> |
| 7139 | {#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}. | 7113 | {#syntax#}T{#endsyntax#} must be a {#syntax#}bool{#endsyntax#}, a float, |
| 7114 | an integer or an enum. | ||
| 7140 | </p> | 7115 | </p> |
| 7141 | <p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> | 7116 | <p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p> |
| 7142 | {#see_also|Compile Variables|cmpxchgStrong#} | 7117 | {#see_also|Compile Variables|cmpxchgStrong#} |
src/codegen.cpp+5-5| ... | @@ -5229,8 +5229,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I | ... | @@ -5229,8 +5229,8 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, IrExecutableGen *executable, I |
| 5229 | // operand needs widening and truncating | 5229 | // operand needs widening and truncating |
| 5230 | ptr_val = LLVMBuildBitCast(g->builder, ptr_val, | 5230 | ptr_val = LLVMBuildBitCast(g->builder, ptr_val, |
| 5231 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); | 5231 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); |
| 5232 | cmp_val = LLVMConstZExt(cmp_val, get_llvm_type(g, instruction->actual_type)); | 5232 | cmp_val = LLVMBuildZExt(g->builder, cmp_val, get_llvm_type(g, instruction->actual_type), ""); |
| 5233 | new_val = LLVMConstZExt(new_val, get_llvm_type(g, instruction->actual_type)); | 5233 | new_val = LLVMBuildZExt(g->builder, new_val, get_llvm_type(g, instruction->actual_type), ""); |
| 5234 | } | 5234 | } |
| 5235 | 5235 | ||
| 5236 | LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order); | 5236 | LLVMAtomicOrdering success_order = to_LLVMAtomicOrdering(instruction->success_order); |
| ... | @@ -5846,7 +5846,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable | ... | @@ -5846,7 +5846,7 @@ static LLVMValueRef ir_render_atomic_rmw(CodeGen *g, IrExecutableGen *executable |
| 5846 | // operand needs widening and truncating | 5846 | // operand needs widening and truncating |
| 5847 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, | 5847 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, ptr, |
| 5848 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); | 5848 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); |
| 5849 | LLVMValueRef casted_operand = LLVMBuildPtrToInt(g->builder, operand, get_llvm_type(g, instruction->actual_type), ""); | 5849 | LLVMValueRef casted_operand = LLVMBuildZExt(g->builder, operand, get_llvm_type(g, instruction->actual_type), ""); |
| 5850 | LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, | 5850 | LLVMValueRef uncasted_result = ZigLLVMBuildAtomicRMW(g->builder, op, casted_ptr, casted_operand, ordering, |
| 5851 | g->is_single_threaded); | 5851 | g->is_single_threaded); |
| 5852 | return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); | 5852 | return LLVMBuildTrunc(g->builder, uncasted_result, get_llvm_type(g, operand_type), ""); |
| ... | @@ -5893,10 +5893,10 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab | ... | @@ -5893,10 +5893,10 @@ static LLVMValueRef ir_render_atomic_store(CodeGen *g, IrExecutableGen *executab |
| 5893 | LLVMValueRef value = ir_llvm_value(g, instruction->value); | 5893 | LLVMValueRef value = ir_llvm_value(g, instruction->value); |
| 5894 | 5894 | ||
| 5895 | if (instruction->actual_type != nullptr) { | 5895 | if (instruction->actual_type != nullptr) { |
| 5896 | // operand needs widening and truncating | 5896 | // operand needs widening |
| 5897 | ptr = LLVMBuildBitCast(g->builder, ptr, | 5897 | ptr = LLVMBuildBitCast(g->builder, ptr, |
| 5898 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); | 5898 | LLVMPointerType(get_llvm_type(g, instruction->actual_type), 0), ""); |
| 5899 | value = LLVMConstZExt(value, get_llvm_type(g, instruction->actual_type)); | 5899 | value = LLVMBuildZExt(g->builder, value, get_llvm_type(g, instruction->actual_type), ""); |
| 5900 | } | 5900 | } |
| 5901 | LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type); | 5901 | LLVMValueRef store_inst = gen_store(g, value, ptr, instruction->ptr->value->type); |
| 5902 | LLVMSetOrdering(store_inst, ordering); | 5902 | LLVMSetOrdering(store_inst, ordering); |
test/stage1/behavior/atomics.zig+2-3| ... | @@ -167,7 +167,7 @@ fn testAtomicRmwFloat() void { | ... | @@ -167,7 +167,7 @@ fn testAtomicRmwFloat() void { |
| 167 | 167 | ||
| 168 | test "atomics with different types" { | 168 | test "atomics with different types" { |
| 169 | testAtomicsWithType(bool, true, false); | 169 | testAtomicsWithType(bool, true, false); |
| 170 | inline for (.{ u1, i5, u33 }) |T| { | 170 | inline for (.{ u1, i5, u15 }) |T| { |
| 171 | var x: T = 0; | 171 | var x: T = 0; |
| 172 | testAtomicsWithType(T, 0, 1); | 172 | testAtomicsWithType(T, 0, 1); |
| 173 | } | 173 | } |
| ... | @@ -175,8 +175,7 @@ test "atomics with different types" { | ... | @@ -175,8 +175,7 @@ test "atomics with different types" { |
| 175 | testAtomicsWithType(i0, 0, 0); | 175 | testAtomicsWithType(i0, 0, 0); |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | // a and b souldn't need to be comptime | 178 | fn testAtomicsWithType(comptime T: type, a: T, b: T) void { |
| 179 | fn testAtomicsWithType(comptime T: type, comptime a: T, comptime b: T) void { | ||
| 180 | var x: T = b; | 179 | var x: T = b; |
| 181 | @atomicStore(T, &x, a, .SeqCst); | 180 | @atomicStore(T, &x, a, .SeqCst); |
| 182 | expect(x == a); | 181 | expect(x == a); |