authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-01 02:37:22-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-01 02:46:37-04:00
log38b5812c4895eb0157f99348f51c40bbd17c3b94
tree4c58a300cfdfe438d7362489e702d7c1f857f695
parentceec2393cfbe20b0993bd7cccb43e930438281fe
signaturelock-open Commit is signed but in an unrecognized format.

allow 128 bit cmpxchg on x86_64


4 files changed, 91 insertions(+), 3 deletions(-)

src/ir.cpp+4-3
...@@ -24735,10 +24735,11 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op...@@ -24735,10 +24735,11 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
24735 operand_type->data.integral.bit_count));24735 operand_type->data.integral.bit_count));
24736 return ira->codegen->builtin_types.entry_invalid;24736 return ira->codegen->builtin_types.entry_invalid;
24737 }24737 }
24738 if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) {24738 uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
24739 if (operand_type->data.integral.bit_count > max_atomic_bits) {
24739 ir_add_error(ira, op,24740 ir_add_error(ira, op,
24740 buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type",24741 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type",
24741 operand_type->data.integral.bit_count));24742 max_atomic_bits, operand_type->data.integral.bit_count));
24742 return ira->codegen->builtin_types.entry_invalid;24743 return ira->codegen->builtin_types.entry_invalid;
24743 }24744 }
24744 if (!is_power_of_2(operand_type->data.integral.bit_count)) {24745 if (!is_power_of_2(operand_type->data.integral.bit_count)) {
src/target.cpp+66
...@@ -863,6 +863,71 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {...@@ -863,6 +863,71 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
863 zig_unreachable();863 zig_unreachable();
864}864}
865865
866uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) {
867 switch (arch) {
868 case ZigLLVM_UnknownArch:
869 zig_unreachable();
870
871 case ZigLLVM_avr:
872 case ZigLLVM_msp430:
873 return 16;
874
875 case ZigLLVM_arc:
876 case ZigLLVM_arm:
877 case ZigLLVM_armeb:
878 case ZigLLVM_hexagon:
879 case ZigLLVM_le32:
880 case ZigLLVM_mips:
881 case ZigLLVM_mipsel:
882 case ZigLLVM_nvptx:
883 case ZigLLVM_ppc:
884 case ZigLLVM_r600:
885 case ZigLLVM_riscv32:
886 case ZigLLVM_sparc:
887 case ZigLLVM_sparcel:
888 case ZigLLVM_tce:
889 case ZigLLVM_tcele:
890 case ZigLLVM_thumb:
891 case ZigLLVM_thumbeb:
892 case ZigLLVM_x86:
893 case ZigLLVM_xcore:
894 case ZigLLVM_amdil:
895 case ZigLLVM_hsail:
896 case ZigLLVM_spir:
897 case ZigLLVM_kalimba:
898 case ZigLLVM_lanai:
899 case ZigLLVM_shave:
900 case ZigLLVM_wasm32:
901 case ZigLLVM_renderscript32:
902 return 32;
903
904 case ZigLLVM_aarch64:
905 case ZigLLVM_aarch64_be:
906 case ZigLLVM_amdgcn:
907 case ZigLLVM_bpfel:
908 case ZigLLVM_bpfeb:
909 case ZigLLVM_le64:
910 case ZigLLVM_mips64:
911 case ZigLLVM_mips64el:
912 case ZigLLVM_nvptx64:
913 case ZigLLVM_ppc64:
914 case ZigLLVM_ppc64le:
915 case ZigLLVM_riscv64:
916 case ZigLLVM_sparcv9:
917 case ZigLLVM_systemz:
918 case ZigLLVM_amdil64:
919 case ZigLLVM_hsail64:
920 case ZigLLVM_spir64:
921 case ZigLLVM_wasm64:
922 case ZigLLVM_renderscript64:
923 return 64;
924
925 case ZigLLVM_x86_64:
926 return 128;
927 }
928 zig_unreachable();
929}
930
866uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {931uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
867 switch (target->os) {932 switch (target->os) {
868 case OsFreestanding:933 case OsFreestanding:
...@@ -1693,3 +1758,4 @@ bool target_supports_libunwind(const ZigTarget *target) {...@@ -1693,3 +1758,4 @@ bool target_supports_libunwind(const ZigTarget *target) {
1693 }1758 }
1694 return true;1759 return true;
1695}1760}
1761
src/target.hpp+1
...@@ -192,6 +192,7 @@ const char *target_arch_musl_name(ZigLLVM_ArchType arch);...@@ -192,6 +192,7 @@ const char *target_arch_musl_name(ZigLLVM_ArchType arch);
192bool target_supports_libunwind(const ZigTarget *target);192bool target_supports_libunwind(const ZigTarget *target);
193193
194uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);194uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
195uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);
195196
196size_t target_libc_count(void);197size_t target_libc_count(void);
197void target_libc_enum(size_t index, ZigTarget *out_target);198void target_libc_enum(size_t index, ZigTarget *out_target);
test/stage1/behavior/atomics.zig+20
...@@ -69,3 +69,23 @@ test "cmpxchg with ptr" {...@@ -69,3 +69,23 @@ test "cmpxchg with ptr" {
69 expect(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);69 expect(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
70 expect(x == &data2);70 expect(x == &data2);
71}71}
72
73test "128-bit cmpxchg" {
74 if (builtin.arch != .x86_64) {
75 return error.SkipZigTest;
76 }
77 var x: u128 align(16) = 1234; // TODO: https://github.com/ziglang/zig/issues/2987
78 if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
79 expect(x1 == 1234);
80 } else {
81 @panic("cmpxchg should have failed");
82 }
83
84 while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
85 expect(x1 == 1234);
86 }
87 expect(x == 5678);
88
89 expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
90 expect(x == 42);
91}