allow 128 bit cmpxchg on x86_64
This commit is contained in:
parent
ceec2393cf
commit
38b5812c48
|
@ -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)) {
|
||||
|
|
|
@ -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:
|
||||
|
@ -1693,3 +1758,4 @@ bool target_supports_libunwind(const ZigTarget *target) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user