aboutsummaryrefslogtreecommitdiff
path: root/lib/std/atomic
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-07-21 03:18:39 -0400
committerGitHub <noreply@github.com>2021-07-21 03:18:39 -0400
commit26984852bdfdbe3564b19f3ff7b3ecfd606c9902 (patch)
treea64c806e3e9900c4eb0cd281a9d6946ce07421f5 /lib/std/atomic
parentbfe20051673e285d3b1788cd637fab9ca84d1cb1 (diff)
parentc39c46c0d12b15874b1586ff47cf473b31867918 (diff)
downloadzig-26984852bdfdbe3564b19f3ff7b3ecfd606c9902.tar.gz
zig-26984852bdfdbe3564b19f3ff7b3ecfd606c9902.zip
Merge pull request #9353 from ziglang/stage2-air
stage2: rework AIR memory layout
Diffstat (limited to 'lib/std/atomic')
-rw-r--r--lib/std/atomic/Atomic.zig88
1 files changed, 70 insertions, 18 deletions
diff --git a/lib/std/atomic/Atomic.zig b/lib/std/atomic/Atomic.zig
index 80fb1ae297..f4e3ebda9d 100644
--- a/lib/std/atomic/Atomic.zig
+++ b/lib/std/atomic/Atomic.zig
@@ -178,26 +178,78 @@ pub fn Atomic(comptime T: type) type {
) u1 {
// x86 supports dedicated bitwise instructions
if (comptime target.cpu.arch.isX86() and @sizeOf(T) >= 2 and @sizeOf(T) <= 8) {
- const instruction = switch (op) {
- .Set => "lock bts",
- .Reset => "lock btr",
- .Toggle => "lock btc",
- };
-
- const suffix = switch (@sizeOf(T)) {
- 2 => "w",
- 4 => "l",
- 8 => "q",
+ const old_bit: u8 = switch (@sizeOf(T)) {
+ 2 => switch (op) {
+ .Set => asm volatile ("lock btsw %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Reset => asm volatile ("lock btrw %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Toggle => asm volatile ("lock btcw %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ },
+ 4 => switch (op) {
+ .Set => asm volatile ("lock btsl %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Reset => asm volatile ("lock btrl %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Toggle => asm volatile ("lock btcl %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ },
+ 8 => switch (op) {
+ .Set => asm volatile ("lock btsq %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Reset => asm volatile ("lock btrq %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ .Toggle => asm volatile ("lock btcq %[bit], %[ptr]"
+ // LLVM doesn't support u1 flag register return values
+ : [result] "={@ccc}" (-> u8)
+ : [ptr] "*p" (&self.value),
+ [bit] "X" (@as(T, bit))
+ : "cc", "memory"
+ ),
+ },
else => @compileError("Invalid atomic type " ++ @typeName(T)),
};
-
- const old_bit = asm volatile (instruction ++ suffix ++ " %[bit], %[ptr]"
- : [result] "={@ccc}" (-> u8) // LLVM doesn't support u1 flag register return values
- : [ptr] "*p" (&self.value),
- [bit] "X" (@as(T, bit))
- : "cc", "memory"
- );
-
return @intCast(u1, old_bit);
}