Skip to content

Commit

Permalink
allow 128 bit cmpxchg on x86_64
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewrk committed Aug 1, 2019
1 parent ceec239 commit 38b5812
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 3 deletions.
7 changes: 4 additions & 3 deletions src/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24735,10 +24735,11 @@ static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op
operand_type->data.integral.bit_count));
return ira->codegen->builtin_types.entry_invalid;
}
if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) {
uint32_t max_atomic_bits = target_arch_largest_atomic_bits(ira->codegen->zig_target->arch);
if (operand_type->data.integral.bit_count > max_atomic_bits) {
ir_add_error(ira, op,
buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type",
operand_type->data.integral.bit_count));
buf_sprintf("expected %" PRIu32 "-bit integer type or smaller, found %" PRIu32 "-bit integer type",
max_atomic_bits, operand_type->data.integral.bit_count));
return ira->codegen->builtin_types.entry_invalid;
}
if (!is_power_of_2(operand_type->data.integral.bit_count)) {
Expand Down
66 changes: 66 additions & 0 deletions src/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,71 @@ uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
zig_unreachable();
}

uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch) {
switch (arch) {
case ZigLLVM_UnknownArch:
zig_unreachable();

case ZigLLVM_avr:
case ZigLLVM_msp430:
return 16;

case ZigLLVM_arc:
case ZigLLVM_arm:
case ZigLLVM_armeb:
case ZigLLVM_hexagon:
case ZigLLVM_le32:
case ZigLLVM_mips:
case ZigLLVM_mipsel:
case ZigLLVM_nvptx:
case ZigLLVM_ppc:
case ZigLLVM_r600:
case ZigLLVM_riscv32:
case ZigLLVM_sparc:
case ZigLLVM_sparcel:
case ZigLLVM_tce:
case ZigLLVM_tcele:
case ZigLLVM_thumb:
case ZigLLVM_thumbeb:
case ZigLLVM_x86:
case ZigLLVM_xcore:
case ZigLLVM_amdil:
case ZigLLVM_hsail:
case ZigLLVM_spir:
case ZigLLVM_kalimba:
case ZigLLVM_lanai:
case ZigLLVM_shave:
case ZigLLVM_wasm32:
case ZigLLVM_renderscript32:
return 32;

case ZigLLVM_aarch64:
case ZigLLVM_aarch64_be:
case ZigLLVM_amdgcn:
case ZigLLVM_bpfel:
case ZigLLVM_bpfeb:
case ZigLLVM_le64:
case ZigLLVM_mips64:
case ZigLLVM_mips64el:
case ZigLLVM_nvptx64:
case ZigLLVM_ppc64:
case ZigLLVM_ppc64le:
case ZigLLVM_riscv64:
case ZigLLVM_sparcv9:
case ZigLLVM_systemz:
case ZigLLVM_amdil64:
case ZigLLVM_hsail64:
case ZigLLVM_spir64:
case ZigLLVM_wasm64:
case ZigLLVM_renderscript64:
return 64;

case ZigLLVM_x86_64:
return 128;
}
zig_unreachable();
}

uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
switch (target->os) {
case OsFreestanding:
Expand Down Expand Up @@ -1693,3 +1758,4 @@ bool target_supports_libunwind(const ZigTarget *target) {
}
return true;
}

1 change: 1 addition & 0 deletions src/target.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ const char *target_arch_musl_name(ZigLLVM_ArchType arch);
bool target_supports_libunwind(const ZigTarget *target);

uint32_t target_arch_pointer_bit_width(ZigLLVM_ArchType arch);
uint32_t target_arch_largest_atomic_bits(ZigLLVM_ArchType arch);

size_t target_libc_count(void);
void target_libc_enum(size_t index, ZigTarget *out_target);
Expand Down
20 changes: 20 additions & 0 deletions test/stage1/behavior/atomics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,23 @@ test "cmpxchg with ptr" {
expect(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
expect(x == &data2);
}

test "128-bit cmpxchg" {
if (builtin.arch != .x86_64) {
return error.SkipZigTest;
}
var x: u128 align(16) = 1234; // TODO: https://github.com/ziglang/zig/issues/2987
if (@cmpxchgWeak(u128, &x, 99, 5678, .SeqCst, .SeqCst)) |x1| {
expect(x1 == 1234);
} else {
@panic("cmpxchg should have failed");
}

while (@cmpxchgWeak(u128, &x, 1234, 5678, .SeqCst, .SeqCst)) |x1| {
expect(x1 == 1234);
}
expect(x == 5678);

expect(@cmpxchgStrong(u128, &x, 5678, 42, .SeqCst, .SeqCst) == null);
expect(x == 42);
}

0 comments on commit 38b5812

Please sign in to comment.