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
2473524735 operand_type->data.integral.bit_count));
2473624736 return ira->codegen->builtin_types.entry_invalid;
2473724737 }
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) {
2473924740 ir_add_error(ira, op,
24740 buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type",
24741 operand_type->data.integral.bit_count));
24741 buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type",
24742 max_atomic_bits, operand_type->data.integral.bit_count));
2474224743 return ira->codegen->builtin_types.entry_invalid;
2474324744 }
2474424745 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) {
863863 zig_unreachable();
864864}
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
866931uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
867932 switch (target->os) {
868933 case OsFreestanding:
......@@ -1693,3 +1758,4 @@ bool target_supports_libunwind(const ZigTarget *target) {
16931758 }
16941759 return true;
16951760}
1761
src/target.hpp+1
......@@ -192,6 +192,7 @@ const char *target_arch_musl_name(ZigLLVM_ArchType arch);
192192bool target_supports_libunwind(const ZigTarget *target);
193193
194194uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
195uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);
195196
196197size_t target_libc_count(void);
197198void target_libc_enum(size_t index, ZigTarget *out_target);
test/stage1/behavior/atomics.zig+20
......@@ -69,3 +69,23 @@ test "cmpxchg with ptr" {
6969 expect(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
7070 expect(x == &data2);
7171}
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}