mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
* Breaking language change: inline assembly must use string literal
syntax. This is in preparation for inline assembly improvements that
involve more integration with the Zig language. This means we cannot
rely on text substitution.
* Liveness: properly handle inline assembly and function calls with
more than 3 operands.
- More than 35 operands is not yet supported. This is a low priority
to implement.
- This required implementation in codegen.zig as well.
* Liveness: fix bug causing incorrect tomb bits.
* Sema: enable switch expressions that are evaluated at compile-time.
- Runtime switch instructions still need to be reworked in this
branch. There was a TODO left here (by me) with a suggestion to do
some bigger changes as part of the AIR memory reworking. Now that
time has come and I plan to honor the suggestion in a future commit
before merging this branch.
* AIR printing: fix missing ')' on alive instructions.
We're back to "hello world" working for the x86_64 backend.
89 lines
3.2 KiB
Zig
89 lines
3.2 KiB
Zig
// SPDX-License-Identifier: MIT
|
|
// Copyright (c) 2015-2021 Zig Contributors
|
|
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
|
|
// The MIT license requires this copyright notice to be included in all copies
|
|
// and substantial portions of the software.
|
|
|
|
const std = @import("std.zig");
|
|
const target = std.Target.current;
|
|
|
|
pub const Ordering = std.builtin.AtomicOrder;
|
|
|
|
pub const Stack = @import("atomic/stack.zig").Stack;
|
|
pub const Queue = @import("atomic/queue.zig").Queue;
|
|
pub const Atomic = @import("atomic/Atomic.zig").Atomic;
|
|
|
|
test "std.atomic" {
|
|
_ = @import("atomic/stack.zig");
|
|
_ = @import("atomic/queue.zig");
|
|
_ = @import("atomic/Atomic.zig");
|
|
}
|
|
|
|
pub inline fn fence(comptime ordering: Ordering) void {
|
|
switch (ordering) {
|
|
.Acquire, .Release, .AcqRel, .SeqCst => {
|
|
@fence(ordering);
|
|
},
|
|
else => {
|
|
@compileLog(ordering, " only applies to a given memory location");
|
|
},
|
|
}
|
|
}
|
|
|
|
pub inline fn compilerFence(comptime ordering: Ordering) void {
|
|
switch (ordering) {
|
|
.Acquire, .Release, .AcqRel, .SeqCst => asm volatile ("" ::: "memory"),
|
|
else => @compileLog(ordering, " only applies to a given memory location"),
|
|
}
|
|
}
|
|
|
|
test "fence/compilerFence" {
|
|
inline for (.{ .Acquire, .Release, .AcqRel, .SeqCst }) |ordering| {
|
|
compilerFence(ordering);
|
|
fence(ordering);
|
|
}
|
|
}
|
|
|
|
/// Signals to the processor that the caller is inside a busy-wait spin-loop.
|
|
pub inline fn spinLoopHint() void {
|
|
switch (target.cpu.arch) {
|
|
// No-op instruction that can hint to save (or share with a hardware-thread)
|
|
// pipelining/power resources
|
|
// https://software.intel.com/content/www/us/en/develop/articles/benefitting-power-and-performance-sleep-loops.html
|
|
.i386, .x86_64 => asm volatile ("pause" ::: "memory"),
|
|
|
|
// No-op instruction that serves as a hardware-thread resource yield hint.
|
|
// https://stackoverflow.com/a/7588941
|
|
.powerpc64, .powerpc64le => asm volatile ("or 27, 27, 27" ::: "memory"),
|
|
|
|
// `isb` appears more reliable for releasing execution resources than `yield`
|
|
// on common aarch64 CPUs.
|
|
// https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8258604
|
|
// https://bugs.mysql.com/bug.php?id=100664
|
|
.aarch64, .aarch64_be, .aarch64_32 => asm volatile ("isb" ::: "memory"),
|
|
|
|
// `yield` was introduced in v6k but is also available on v6m.
|
|
// https://www.keil.com/support/man/docs/armasm/armasm_dom1361289926796.htm
|
|
.arm, .armeb, .thumb, .thumbeb => {
|
|
const can_yield = comptime std.Target.arm.featureSetHasAny(target.cpu.features, .{
|
|
.has_v6k, .has_v6m,
|
|
});
|
|
if (can_yield) {
|
|
asm volatile ("yield" ::: "memory");
|
|
} else {
|
|
asm volatile ("" ::: "memory");
|
|
}
|
|
},
|
|
// Memory barrier to prevent the compiler from optimizing away the spin-loop
|
|
// even if no hint_instruction was provided.
|
|
else => asm volatile ("" ::: "memory"),
|
|
}
|
|
}
|
|
|
|
test "spinLoopHint" {
|
|
var i: usize = 10;
|
|
while (i > 0) : (i -= 1) {
|
|
spinLoopHint();
|
|
}
|
|
}
|