From c5720a962abe2740554126f18ee49cac2680c20a Mon Sep 17 00:00:00 2001 From: Lucian Radu Teodorescu Date: Fri, 20 Dec 2024 22:37:37 +0200 Subject: [PATCH 1/3] Add atomics support in the standard library --- .gitignore | 1 + .../Sources/LowLevel/Threading/Atomic.hylo | 122 + .../LowLevel/Threading/AtomicOrderings.hylo | 167 + .../Threading/AtomicRepresentable.hylo | 131 + .../LowLevel/Threading/PlatformAtomic.hylo | 55 + .../LowLevel/Threading/PlatformAtomics.hylo | 2922 +++++++++++++++++ .../Threading/PlatformAtomics.hylo.gyb | 99 + .../TestCases/AtomicOperations.hylo | 146 + Tools/HyloAtomics.py | 51 + 9 files changed, 3694 insertions(+) create mode 100644 StandardLibrary/Sources/LowLevel/Threading/Atomic.hylo create mode 100644 StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo create mode 100644 StandardLibrary/Sources/LowLevel/Threading/AtomicRepresentable.hylo create mode 100644 StandardLibrary/Sources/LowLevel/Threading/PlatformAtomic.hylo create mode 100644 StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo create mode 100644 StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb create mode 100644 Tests/EndToEndTests/TestCases/AtomicOperations.hylo create mode 100644 Tools/HyloAtomics.py diff --git a/.gitignore b/.gitignore index 370f1b9b3..3b0fff4ed 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ **.lib **.7z llvm.pc +Tools/__pycache__ diff --git a/StandardLibrary/Sources/LowLevel/Threading/Atomic.hylo b/StandardLibrary/Sources/LowLevel/Threading/Atomic.hylo new file mode 100644 index 000000000..f7c97309f --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/Atomic.hylo @@ -0,0 +1,122 @@ + +/// Defines atomic operations for `T`. +public type Atomic: SemiRegular { + + /// The storage for the atomic operations. + var storage: T.AtomicRepresentation + + /// Initializes `self` with the zero value. + public init() { + &storage = .new() + } + + /// Initializes `self` with `value`. + public init(value: sink T) { + &storage = .new() + store(value, ordering: /*AtomicStoreOrdering.relaxed*/ .new(value: 0)) + // TODO: using atomic ordering constants produce linker errors + } + + /// Atomically load the value from the atomic, using `ordering`. + public fun load(ordering: AtomicLoadOrdering) -> T { + return T.decodeAtomicRepresentation(storage.load(ordering: ordering)) + } + + /// Atomically store `value` into the atomic, using `ordering`. + public fun store(_ value: sink T, ordering: AtomicStoreOrdering) inout { + storage.store(T.encodeAtomicRepresentation(value), ordering: ordering) + } + + /// Atomically exchanges the value in the atomic with `desired`, using `ordering`. + public fun exchange(desired: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.exchange(desired: T.encodeAtomicRepresentation(desired), ordering: ordering)) + } + + /// Atomically exchanges the atomic with `desired`, if the original value is equal to `expected`, using `ordering`. + /// Returns a tuple containing the original value and a boolean indicating whether the exchange was successful. + public fun compare_and_exchange(expected: sink T, desired: sink T, ordering: AtomicUpdateOrdering) inout -> {exchanged: Bool, original: T} { + let r = storage.compare_and_exchange( + expected: T.encodeAtomicRepresentation(expected), + desired: T.encodeAtomicRepresentation(desired), + success_ordering: ordering, + failure_ordering: failure_ordering(for: ordering)) + return (exchanged: r.0, original: T.decodeAtomicRepresentation(r.1)) + } + + /// Atomically exchanges the atomic with `desired`, if the original value is equal to `expected`, using `success_ordering` for the update, and `failure_ordering` for loading the new value in case of failure. + /// Returns a tuple containing the original value and a boolean indicating whether the exchange was successful. + public fun compare_and_exchange(expected: sink T, desired: sink T, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: T} { + let r = storage.compare_and_exchange( + expected: T.encodeAtomicRepresentation(expected), + desired: T.encodeAtomicRepresentation(desired), + success_ordering: success_ordering, + failure_ordering: failure_ordering) + return (exchanged: r.0, original: T.decodeAtomicRepresentation(r.1)) + } + + /// Same as `compare_and_exchange`, but may fail spuriously. + public fun weak_compare_and_exchange(expected: sink T, desired: sink T, ordering: AtomicUpdateOrdering) inout -> {exchanged: Bool, original: T} { + let r = storage.weak_compare_and_exchange( + expected: T.encodeAtomicRepresentation(expected), + desired: T.encodeAtomicRepresentation(desired), + success_ordering: ordering, + failure_ordering: failure_ordering(for: ordering)) + return (exchanged: r.0, original: T.decodeAtomicRepresentation(r.1)) + } + + /// Same as `compare_and_exchange`, but may fail spuriously. + public fun weak_compare_and_exchange(expected: sink T, desired: sink T, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: T} { + let r = storage.weak_compare_and_exchange( + expected: T.encodeAtomicRepresentation(expected), + desired: T.encodeAtomicRepresentation(desired), + success_ordering: success_ordering, + failure_ordering: failure_ordering) + return (exchanged: r.0, original: T.decodeAtomicRepresentation(r.1)) + } + +} + +/// Atomic operations for integer types +public extension Atomic where T.AtomicRepresentation: IntegerPlatformAtomic, T: Numeric { + + /// Atomically updates `this` by adding `value` to it, using `ordering`, and return the original value. + public fun fetch_add(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_add(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by subtracting `value` from it, using `ordering`, and return the original value. + public fun fetch_sub(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_sub(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by using the maximum of `value` and itself, using `ordering`, and return the original value. + public fun fetch_max(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_max(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by using the minimum of `value` and itself, using `ordering`, and return the original value. + public fun fetch_min(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_min(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by performing a bitwise AND of `value` and itself, using `ordering`, and return the original value. + public fun fetch_and(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_and(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by performing a bitwise NAND of `value` and itself, using `ordering`, and return the original value. + public fun fetch_nand(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_nand(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by performing a bitwise OR of `value` and itself, using `ordering`, and return the original value. + public fun fetch_or(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_or(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + + /// Atomically updates `this` by performing a bitwise XOR of `value` and itself, using `ordering`, and return the original value. + public fun fetch_xor(_ value: sink T, ordering: AtomicUpdateOrdering) inout -> T { + return T.decodeAtomicRepresentation(storage.fetch_xor(T.encodeAtomicRepresentation(value), ordering: ordering)) + } + +} diff --git a/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo b/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo new file mode 100644 index 000000000..0eec39a09 --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo @@ -0,0 +1,167 @@ +/// Specifies the memory ordering sematics for an atomic load operation. +public type AtomicLoadOrdering: Regular { + + public memberwise init + + internal let value: Int + +} + +public extension AtomicLoadOrdering { + + /// Guarantees the atomicity of the load operation, but does not impose any ordering constraints + /// on other memory operations. + /// + /// Corresponds to the `memory_order_relaxed` C++ memory ordering. + public static let relaxed: AtomicLoadOrdering = .new(value: 0) + + /// An acquiring load operation syncrhonizes with a releasing store operation on the same atomic + /// variable. The thread performing the acquiring operation agrees with the thread performing the + /// releasing operation that all the subsequent load operations (atomic or not) on the acquiring + /// thread happen after the atomic operation itself. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before the + /// atomic load. This barrier can be used to acquire a lock. + /// + /// Corresponds to the `memory_order_acquire` C++ memory ordering. + public static let acquiring: AtomicLoadOrdering = .new(value: 1) + + /// A sequentially consistent load operation provides the same guarantees as an acquiring load + /// and also guarantees that all sequentially consistent operations on the atomic variable will + /// have a total squential order, across all threads. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before and + /// after the atomic load. + /// + /// Corresponds to the `memory_order_seq_cst` C++ memory ordering. + public static let sequentially_consistent: AtomicLoadOrdering = .new(value: 4) + +} + +/// Specifies the memory ordering sematics for an atomic store operation. +public type AtomicStoreOrdering: Regular { + + public memberwise init + + internal let value: Int + +} + +public extension AtomicStoreOrdering { + + /// Guarantees the atomicity of the store operation, but does not impose any ordering constraints + /// on other memory operations. + /// + /// Corresponds to the `memory_order_relaxed` C++ memory ordering. + public static let relaxed: AtomicStoreOrdering = .new(value: 0) + + /// A releasing store operation syncrhonizes with an acquiring load operation on the same atomic + /// variable. The thread performing the releasing operation agrees with the thread performing the + /// acquiring operation that all the previous store operations (atomic or not) on the releasing + /// thread will be seen before the atomic operation itself. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered after the + /// atomic store. This barrier can be used to release a lock. + /// + /// Corresponds to the `memory_order_release` C++ memory ordering. + public static let releasing: AtomicStoreOrdering = .new(value: 2) + + /// A sequentially consistent store operation provides the same guarantees as a releasing store + /// and also guarantees that all sequentially consistent operations on the atomic variable will + /// have a total squential order, across all threads. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before and + /// after the atomic store. + /// + /// Corresponds to the `memory_order_seq_cst` C++ memory ordering. + public static let sequentially_consistent: AtomicStoreOrdering = .new(value: 4) + +} + +/// Specifies the memory ordering sematics for an atomic read-modify-write (update) operation. +public type AtomicUpdateOrdering: Regular { + + public memberwise init + + internal let value: Int + +} + +public extension AtomicUpdateOrdering { + + /// Guarantees the atomicity of the load operation, but does not impose any ordering constraints + /// on other memory operations. + /// + /// Corresponds to the `memory_order_relaxed` C++ memory ordering. + public static let relaxed: AtomicUpdateOrdering = .new(value: 0) + + /// An acquiring update operation syncrhonizes with a releasing store operation on the same + /// atomic variable whose value it reads. The thread performing the acquiring operation agrees + /// with the thread performing the releasing operation that all the subsequent load operations + /// (atomic or not) on the acquiring thread happen after the atomic operation itself. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before the + /// atomic operation. This barrier can be used to acquire a lock. + /// + /// Corresponds to the `memory_order_acquire` C++ memory ordering. + public static let acquiring: AtomicUpdateOrdering = .new(value: 1) + + /// A releasing update operation syncrhonizes with an acquiring load operation on the same atomic + /// variable that reads the updated value. The thread performing the releasing operation agrees + /// with the thread performing the acquiring operation that all the previous store operations + /// (atomic or not) on the releasing thread will be seen before the atomic operation itself. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered after the + /// atomic update. This barrier can be used to release a lock. + /// + /// Corresponds to the `memory_order_release` C++ memory ordering. + public static let releasing: AtomicUpdateOrdering = .new(value: 2) + + /// An acquiring and releasing update operation syncrhonizes with both acquiring loads that read + /// the updated value and with the releasing stores that update the value that this update reads. + /// The thread performing the update operation agrees with the threads performing the acquiring + /// load that all the previous store operations (atomic or not) on the releasing thread will be + /// seen before the atomic operation itself. The thread performing the update operation also + /// agrees with the threads performing the releasing store of the value read by the update that + /// all the previous store operations (atomic or not) on the updating thread happen before the + /// update. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before and + /// after the atomic update. + /// + /// Corresponds to the `memory_order_seq_cst` C++ memory ordering. + public static let acquiring_and_releasing: AtomicUpdateOrdering = .new(value: 3) + + /// A sequentially consistent update operation provides the same guarantees as an acquiring and + /// releasing update and also guarantees that all sequentially consistent operations on the + /// atomic variable will have a total squential order, across all threads. + /// + /// Provides a barrier that prevents read/write memory operations to be reordered before and + /// after the atomic update. + /// + /// Corresponds to the `memory_order_seq_cst` C++ memory ordering. + public static let sequentially_consistent: AtomicUpdateOrdering = .new(value: 4) + +} + +/// Transforms from an atomic update ordering to a corresponding atomic load ordering, to be used +/// in `compare_and_exchange` operations to get the failure ordering from the success ordering. +// TODO: this should be internal, but we have a bug that generates a linker error +public fun failure_ordering(for ordering: AtomicUpdateOrdering) -> AtomicLoadOrdering { + if ordering == /*AtomicUpdateOrdering.relaxed*/ AtomicUpdateOrdering(value: 0) { + return /*AtomicLoadOrdering.relaxed.copy()*/ AtomicLoadOrdering(value: 0) + } + if ordering == /*AtomicUpdateOrdering.acquiring*/ AtomicUpdateOrdering(value: 1) { + return /*AtomicLoadOrdering.acquiring.copy()*/ AtomicLoadOrdering(value: 1) + } + if ordering == /*AtomicUpdateOrdering.releasing*/ AtomicUpdateOrdering(value: 2) { + return /*AtomicLoadOrdering.relaxed.copy()*/ AtomicLoadOrdering(value: 0) + } + if ordering == /*AtomicUpdateOrdering.acquiring_and_releasing*/ AtomicUpdateOrdering(value: 3) { + return /*AtomicLoadOrdering.acquiring.copy()*/ AtomicLoadOrdering(value: 1) + } + if ordering == /*AtomicUpdateOrdering.sequentially_consistent*/ AtomicUpdateOrdering(value: 4) { + return /*AtomicLoadOrdering.sequentially_consistent.copy()*/ AtomicLoadOrdering(value: 4) + } + trap() +} diff --git a/StandardLibrary/Sources/LowLevel/Threading/AtomicRepresentable.hylo b/StandardLibrary/Sources/LowLevel/Threading/AtomicRepresentable.hylo new file mode 100644 index 000000000..608f26bd4 --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/AtomicRepresentable.hylo @@ -0,0 +1,131 @@ + +/// A type that can be used used for atomic operations. +public trait AtomicRepresentable: Regular { + + /// The underlying platform type. + type AtomicRepresentation: PlatformAtomic; + + /// Encode `value` into the atomic representation. + static fun encodeAtomicRepresentation(_ value: sink Self) -> AtomicRepresentation.Value + + /// Decode `storage` into a value of `Self`. + static fun decodeAtomicRepresentation(_ storage: sink AtomicRepresentation.Value) -> Self + +} + +public conformance Bool: AtomicRepresentable { + + public typealias AtomicRepresentation = Int8AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> Int8 { + if value { 1 } else { 0 } + } + + public static fun decodeAtomicRepresentation(_ storage: sink Int8) -> Self { + storage != 0 + } +} + +public conformance Int: AtomicRepresentable { + + public typealias AtomicRepresentation = IntAtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> Int { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink Int) -> Self { + storage + } +} + +public conformance Int8: AtomicRepresentable { + + public typealias AtomicRepresentation = Int8AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> Int8 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink Int8) -> Self { + storage + } +} + +public conformance Int32: AtomicRepresentable { + + public typealias AtomicRepresentation = Int32AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> Int32 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink Int32) -> Self { + storage + } +} + +public conformance Int64: AtomicRepresentable { + + public typealias AtomicRepresentation = Int64AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> Int64 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink Int64) -> Self { + storage + } +} + +public conformance UInt: AtomicRepresentable { + + public typealias AtomicRepresentation = UIntAtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> UInt { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink UInt) -> Self { + storage + } +} + +public conformance UInt8: AtomicRepresentable { + + public typealias AtomicRepresentation = UInt8AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> UInt8 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink UInt8) -> Self { + storage + } +} + +public conformance UInt32: AtomicRepresentable { + + public typealias AtomicRepresentation = UInt32AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> UInt32 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink UInt32) -> Self { + storage + } +} + +public conformance UInt64: AtomicRepresentable { + + public typealias AtomicRepresentation = UInt64AtomicRepresentation + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> UInt64 { + value + } + + public static fun decodeAtomicRepresentation(_ storage: sink UInt64) -> Self { + storage + } +} diff --git a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomic.hylo b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomic.hylo new file mode 100644 index 000000000..2f31bf8d6 --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomic.hylo @@ -0,0 +1,55 @@ +/// A platform-specific atomic type. +trait PlatformAtomic: Regular { + + /// The value type of the atomic. + type Value: Regular + + /// Initializes the atomic with the "zero" value. + init() + + /// Atomically load the value from the atomic, using `ordering`. + fun load(ordering: AtomicLoadOrdering) -> Value + + /// Atomically store `value` into the atomic, using `ordering`. + fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout + + /// Atomically exchanges the value in the atomic with `desired`, using `ordering`. + fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically exchanges the atomic with `desired`, if the original value is equal to `expected`, using `success_ordering` for the update, and `failure_ordering` for loading the new value in case of failure. + /// Returns a tuple containing the original value and a boolean indicating whether the exchange was successful. + fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} + + /// Same as `compare_and_exchange`, but may fail spuriously. + fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} + +} + +/// A platform-specific atomic integer type. +trait IntegerPlatformAtomic: PlatformAtomic { + + /// Atomically updates `this` by adding `value` to it, using `ordering`, and return the original value. + fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by subtracting `value` from it, using `ordering`, and return the original value. + fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by using the maximum of `value` and itself, using `ordering`, and return the original value. + fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by using the minimum of `value` and itself, using `ordering`, and return the original value. + fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by performing a bitwise AND of `value` and itself, using `ordering`, and return the original value. + fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by performing a bitwise NAND of `value` and itself, using `ordering`, and return the original value. + fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by performing a bitwise OR of `value` and itself, using `ordering`, and return the original value. + fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + + /// Atomically updates `this` by performing a bitwise XOR of `value` and itself, using `ordering`, and return the original value. + fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value + +} diff --git a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo new file mode 100644 index 000000000..7aa5aa454 --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo @@ -0,0 +1,2922 @@ + + +/////////////////////////////////////////////////////////////////////////////// +// MARK: IntAtomicRepresentation + +/// An atomic representation of Int. +public type IntAtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: Int + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = Int(value: Builtin.zeroinitializer_word()) + } + + public typealias Value = Int + +} + +public conformance IntAtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_word(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_word(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_word(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_word(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_word(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_word(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_word(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_max_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_max_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_max_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_max_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_max_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_min_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_min_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_min_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_min_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_min_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: Int8AtomicRepresentation + +/// An atomic representation of Int8. +public type Int8AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: Int8 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = Int8(value: Builtin.zeroinitializer_i8()) + } + + public typealias Value = Int8 + +} + +public conformance Int8AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i8(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i8(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i8(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i8(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i8(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i8(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i8(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_max_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_max_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_max_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_max_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_max_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_min_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_min_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_min_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_min_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_min_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: Int32AtomicRepresentation + +/// An atomic representation of Int32. +public type Int32AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: Int32 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = Int32(value: Builtin.zeroinitializer_i32()) + } + + public typealias Value = Int32 + +} + +public conformance Int32AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i32(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i32(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i32(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i32(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i32(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i32(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i32(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_max_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_max_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_max_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_max_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_max_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_min_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_min_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_min_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_min_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_min_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: Int64AtomicRepresentation + +/// An atomic representation of Int64. +public type Int64AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: Int64 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = Int64(value: Builtin.zeroinitializer_i64()) + } + + public typealias Value = Int64 + +} + +public conformance Int64AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i64(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i64(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i64(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i64(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i64(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i64(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i64(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_max_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_max_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_max_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_max_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_max_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_min_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_min_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_min_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_min_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_min_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: UIntAtomicRepresentation + +/// An atomic representation of UInt. +public type UIntAtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: UInt + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = UInt(value: Builtin.zeroinitializer_word()) + } + + public typealias Value = UInt + +} + +public conformance UIntAtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_word(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_word(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_word(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_word(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_word(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_word(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_word(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_word(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_word(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umax_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umax_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umax_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umax_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umax_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umin_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umin_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umin_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umin_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umin_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_word(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_word(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: UInt8AtomicRepresentation + +/// An atomic representation of UInt8. +public type UInt8AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: UInt8 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = UInt8(value: Builtin.zeroinitializer_i8()) + } + + public typealias Value = UInt8 + +} + +public conformance UInt8AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i8(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i8(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i8(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i8(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i8(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i8(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i8(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i8(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i8(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umax_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umax_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umax_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umax_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umax_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umin_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umin_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umin_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umin_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umin_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i8(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i8(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: UInt32AtomicRepresentation + +/// An atomic representation of UInt32. +public type UInt32AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: UInt32 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = UInt32(value: Builtin.zeroinitializer_i32()) + } + + public typealias Value = UInt32 + +} + +public conformance UInt32AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i32(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i32(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i32(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i32(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i32(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i32(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i32(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i32(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i32(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umax_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umax_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umax_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umax_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umax_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umin_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umin_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umin_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umin_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umin_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i32(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i32(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + +/////////////////////////////////////////////////////////////////////////////// +// MARK: UInt64AtomicRepresentation + +/// An atomic representation of UInt64. +public type UInt64AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: UInt64 + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = UInt64(value: Builtin.zeroinitializer_i64()) + } + + public typealias Value = UInt64 + +} + +public conformance UInt64AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { + if /*ordering == AtomicLoadOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_load_relaxed_i64(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_load_acquire_i64(Builtin.address(of: self.value.value))) + } + if /*ordering == AtomicLoadOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_load_seqcst_i64(Builtin.address(of: self.value.value))) + } + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { + if /*ordering == AtomicStoreOrdering.relaxed*/ ordering.value == 0 { + Builtin.atomic_store_relaxed_i64(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.releasing*/ ordering.value == 2 { + Builtin.atomic_store_release_i64(Builtin.address(of: self.value.value), value.value) + return + } + if /*ordering == AtomicStoreOrdering.sequentially_consistent*/ ordering.value == 4 { + Builtin.atomic_store_seqcst_i64(Builtin.address(of: self.value.value), value.value) + return + } + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_relaxed_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_relaxed_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_relaxed_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acquire_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acquire_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acquire_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_release_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_release_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_release_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_acqrel_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_acqrel_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_acqrel_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchg_seqcst_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchg_seqcst_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchg_seqcst_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { + if /*success_ordering == AtomicUpdateOrdering.relaxed*/ success_ordering.value == 0 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_relaxed_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_relaxed_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_relaxed_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring*/ success_ordering.value == 1 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acquire_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acquire_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acquire_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.releasing*/ success_ordering.value == 2 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_release_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_release_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_release_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ success_ordering.value == 3 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_acqrel_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_acqrel_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_acqrel_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + if /*success_ordering == AtomicUpdateOrdering.sequentially_consistent*/ success_ordering.value == 4 { + if /*failure_ordering == AtomicLoadOrdering.relaxed*/ failure_ordering.value == 0 { + let r = Builtin.atomic_cmpxchgweak_seqcst_relaxed_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.acquiring*/ failure_ordering.value == 1 { + let r = Builtin.atomic_cmpxchgweak_seqcst_acquire_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + if /*failure_ordering == AtomicLoadOrdering.sequentially_consistent*/ failure_ordering.value == 4 { + let r = Builtin.atomic_cmpxchgweak_seqcst_seqcst_i64(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } + } + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_swap_relaxed_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_swap_acquire_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_swap_release_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_swap_acqrel_i64(Builtin.address(of: self.value.value), desired.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_swap_seqcst_i64(Builtin.address(of: self.value.value), desired.value)) + } + trap() + } + + public fun fetch_add(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_add_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_add_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_add_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_add_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_add_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_sub(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_sub_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_sub_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_sub_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_sub_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_sub_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_max(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umax_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umax_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umax_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umax_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umax_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_min(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_umin_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_umin_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_umin_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_umin_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_umin_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_and(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_and_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_and_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_and_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_and_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_and_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_nand(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_nand_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_nand_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_nand_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_nand_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_nand_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_or(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_or_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_or_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_or_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_or_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_or_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + public fun fetch_xor(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { + if /*ordering == AtomicUpdateOrdering.relaxed*/ ordering.value == 0 { + return Value(value: Builtin.atomic_xor_relaxed_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring*/ ordering.value == 1 { + return Value(value: Builtin.atomic_xor_acquire_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.releasing*/ ordering.value == 2 { + return Value(value: Builtin.atomic_xor_release_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.acquiring_and_releasing*/ ordering.value == 3 { + return Value(value: Builtin.atomic_xor_acqrel_i64(Builtin.address(of: self.value.value), value.value)) + } + if /*ordering == AtomicUpdateOrdering.sequentially_consistent*/ ordering.value == 4 { + return Value(value: Builtin.atomic_xor_seqcst_i64(Builtin.address(of: self.value.value), value.value)) + } + trap() + } + +} + diff --git a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb new file mode 100644 index 000000000..c11dd2b6c --- /dev/null +++ b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb @@ -0,0 +1,99 @@ +% # This is a template for PlatformAtomics.hylo file. +% # Generate it by running the following command, from the root of the repository: +% # python3 Tools/gyb.py StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb -o StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo --line-directive= + +% from HyloAtomics import * + +% for (type, builtin, rmw_ops) in numeric_types: +/////////////////////////////////////////////////////////////////////////////// +// MARK: ${type}AtomicRepresentation + +/// An atomic representation of ${type}. +public type ${type}AtomicRepresentation: Regular { + + /// The undelying value, for which we expose atomic operations. + internal let value: ${type} + + public memberwise init + + /// Initializes `self` with the zero value. + public init() { + &self.value = ${type}(value: Builtin.zeroinitializer_${builtin}()) + } + + public typealias Value = ${type} + +} + +public conformance ${type}AtomicRepresentation: IntegerPlatformAtomic { + + public fun load(ordering: AtomicLoadOrdering) -> Value { +% for (hylo_ordering, native_ordering, value) in load_orderings: + if /*ordering == AtomicLoadOrdering.${hylo_ordering}*/ ordering.value == ${value} { + return Value(value: Builtin.atomic_load_${native_ordering}_${builtin}(Builtin.address(of: self.value.value))) + } +% end + trap() + } + + public fun store(_ value: sink Value, ordering: AtomicStoreOrdering) inout { +% for (hylo_ordering, native_ordering, value) in store_orderings: + if /*ordering == AtomicStoreOrdering.${hylo_ordering}*/ ordering.value == ${value} { + Builtin.atomic_store_${native_ordering}_${builtin}(Builtin.address(of: self.value.value), value.value) + return + } +% end + trap() + } + + public fun compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { +% for (hylo_s_ordering, native_s_ordering, s_value) in update_orderings: + if /*success_ordering == AtomicUpdateOrdering.${hylo_s_ordering}*/ success_ordering.value == ${s_value} { +% for (hylo_f_ordering, native_f_ordering, f_value) in load_orderings: + if /*failure_ordering == AtomicLoadOrdering.${hylo_f_ordering}*/ failure_ordering.value == ${f_value} { + let r = Builtin.atomic_cmpxchg_${native_s_ordering}_${native_f_ordering}_${builtin}(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } +% end + } +% end + trap() + } + + public fun weak_compare_and_exchange(expected: sink Value, desired: sink Value, success_ordering: AtomicUpdateOrdering, failure_ordering: AtomicLoadOrdering) inout -> {exchanged: Bool, original: Value} { +% for (hylo_s_ordering, native_s_ordering, s_value) in update_orderings: + if /*success_ordering == AtomicUpdateOrdering.${hylo_s_ordering}*/ success_ordering.value == ${s_value} { +% for (hylo_f_ordering, native_f_ordering, f_value) in load_orderings: + if /*failure_ordering == AtomicLoadOrdering.${hylo_f_ordering}*/ failure_ordering.value == ${f_value} { + let r = Builtin.atomic_cmpxchgweak_${native_s_ordering}_${native_f_ordering}_${builtin}(Builtin.address(of: self.value.value), expected.value, desired.value) + return (exchanged: Bool(value: r.1), original: Value(value: r.0)) + } +% end + } +% end + trap() + } + + public fun exchange(desired: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { +% for (hylo_ordering, native_ordering, value) in update_orderings: + if /*ordering == AtomicUpdateOrdering.${hylo_ordering}*/ ordering.value == ${value} { + return Value(value: Builtin.atomic_swap_${native_ordering}_${builtin}(Builtin.address(of: self.value.value), desired.value)) + } +% end + trap() + } + +% for oper in rmw_ops: + public fun ${ops_to_hylo[oper]}(_ value: sink Value, ordering: AtomicUpdateOrdering) inout -> Value { +% for (hylo_ordering, native_ordering, value) in update_orderings: + if /*ordering == AtomicUpdateOrdering.${hylo_ordering}*/ ordering.value == ${value} { + return Value(value: Builtin.atomic_${oper}_${native_ordering}_${builtin}(Builtin.address(of: self.value.value), value.value)) + } +% end + trap() + } +% end + +} + +% end diff --git a/Tests/EndToEndTests/TestCases/AtomicOperations.hylo b/Tests/EndToEndTests/TestCases/AtomicOperations.hylo new file mode 100644 index 000000000..fb69c2587 --- /dev/null +++ b/Tests/EndToEndTests/TestCases/AtomicOperations.hylo @@ -0,0 +1,146 @@ +//- compileAndRun expecting: .success + +fun testBasicAtomicOperations(value1: T, value2: T) { + precondition(value1 != value2) + + // construction + var atomic: Atomic = .new() + var a2: Atomic = .new(value: value1.copy()) + precondition(atomic != a2) + + // store + atomic.store(value1.copy(), ordering: .new(value: 0)) + precondition(atomic == a2) + + // load + precondition(atomic.load(ordering: .new(value: 0)) == value1) + + // exchange + let old1 = atomic.exchange(desired: value2.copy(), ordering: .new(value: 0)) + precondition(old1 == value1) + precondition(atomic.load(ordering: .new(value: 0)) == value2) + + // compare_and_exchange + let r1 = atomic.compare_and_exchange(expected: value1.copy(), desired: value2.copy(), ordering: .new(value: 0)) + precondition(r1.0 == false) + precondition(r1.1 == value2) + let r2 = atomic.compare_and_exchange(expected: value2.copy(), desired: value1.copy(), ordering: .new(value: 0)) + precondition(r2.0 == true) + precondition(r2.1 == value2) + + // weak_compare_and_exchange + let r3 = atomic.weak_compare_and_exchange(expected: value2.copy(), desired: value1.copy(), ordering: .new(value: 0)) + precondition(r3.0 == false) + precondition(r3.1 == value1) + let r4 = atomic.weak_compare_and_exchange(expected: value1.copy(), desired: value2.copy(), ordering: .new(value: 0)) + precondition(r4.0 == true) + precondition(r4.1 == value1) +} + +fun testBasicAtomicOperationsAllTypes() { + testBasicAtomicOperations(value1: true, value2: false) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) + testBasicAtomicOperations(value1: 11, value2: 13) +} + +fun testIntegerAtomicOperations() { + var atomic: Atomic = .new(value: 11) + + let old1 = atomic.fetch_add(1, ordering: .new(value: 0)) + precondition(old1 == 11) + precondition(atomic.load(ordering: .new(value: 0)) == 12) + + let old2 = atomic.fetch_sub(1, ordering: .new(value: 0)) + precondition(old2 == 12) + precondition(atomic.load(ordering: .new(value: 0)) == 11) + + let old3 = atomic.fetch_max(19, ordering: .new(value: 0)) + precondition(old3 == 11) + precondition(atomic.load(ordering: .new(value: 0)) == 19) + + let old4 = atomic.fetch_min(13, ordering: .new(value: 0)) + precondition(old4 == 19) + precondition(atomic.load(ordering: .new(value: 0)) == 13) + + let old5 = atomic.fetch_and(0xfc, ordering: .new(value: 0)) + precondition(old5 == 13) + precondition(atomic.load(ordering: .new(value: 0)) == 0x0c) + + let old6 = atomic.fetch_or(0xf0, ordering: .new(value: 0)) + precondition(old6 == 0x0c) + precondition(atomic.load(ordering: .new(value: 0)) == 0xfc) + + let old7 = atomic.fetch_xor(0xf0, ordering: .new(value: 0)) + precondition(old7 == 0xfc) + precondition(atomic.load(ordering: .new(value: 0)) == 0x0c) + + let old8 = atomic.fetch_xor(0xff, ordering: .new(value: 0)) + precondition(old8 == 0x0c) + precondition(atomic.load(ordering: .new(value: 0)) == 0xf3) +} + +type MyState: Regular { + + internal let flag: Bool + internal let counter: Int + + internal memberwise init + + public init() { + &self.flag = false + &self.counter = 0 + } + +} + +conformance MyState: AtomicRepresentable { + + /// The underlying platform type. + public typealias AtomicRepresentation = UInt64.AtomicRepresentation; + + public static fun encodeAtomicRepresentation(_ value: sink Self) -> UInt64 { + var r: UInt64 = .new(truncating_or_extending: value.counter) + &r &= 0x7fffffffffffffff + if value.flag { + &r |= 0x8000000000000000 + } + return r + } + + /// Decode `storage` into a value of `Self`. + public static fun decodeAtomicRepresentation(_ storage: sink UInt64) -> Self { + let flag = (storage & 0x8000000000000000) != 0 + let counter = Int(truncating_or_extending: storage & 0x7fffffffffffffff) + return .new(flag: flag, counter: counter) + } + +} + +fun testCustomAtomicType() { + // TODO: IR -> LLVM transpilation fails when we instantiate an `Atomic` type. + // var atomic: Atomic = .new() + + // atomic.store(.new(flag: true, counter: 11), ordering: .new(value: 0)) + + // let v = atomic.load(ordering: .new(value: 0)) + // precondition(v.flag == true) + // precondition(v.counter == 11) + + // // compare_and_exchange + // let r1 = atomic.compare_and_exchange(expected: .new(flag: false, counter: 19), desired: .new(flag: true, counter: 11), ordering: .new(value: 0)) + // precondition(r1.0 == false) + // precondition(r1.1.flag == false) + // precondition(r1.1.counter == 19) +} + +public fun main() { + testBasicAtomicOperationsAllTypes() + testIntegerAtomicOperations() + testCustomAtomicType() +} diff --git a/Tools/HyloAtomics.py b/Tools/HyloAtomics.py new file mode 100644 index 000000000..16cfd4479 --- /dev/null +++ b/Tools/HyloAtomics.py @@ -0,0 +1,51 @@ +numeric_types = [ + # type, buliltin, rmw_ops + ("Int", "word", ["add", "sub", "max", "min", "and", "nand", "or", "xor"]), + ("Int8", "i8", ["add", "sub", "max", "min", "and", "nand", "or", "xor"]), + ("Int32", "i32", ["add", "sub", "max", "min", "and", "nand", "or", "xor"]), + ("Int64", "i64", ["add", "sub", "max", "min", "and", "nand", "or", "xor"]), + ("UInt", "word", ["add", "sub", "umax", "umin", "and", "nand", "or", "xor"]), + ("UInt8", "i8", ["add", "sub", "umax", "umin", "and", "nand", "or", "xor"]), + ("UInt32", "i32", ["add", "sub", "umax", "umin", "and", "nand", "or", "xor"]), + ("UInt64", "i64", ["add", "sub", "umax", "umin", "and", "nand", "or", "xor"]), +] + +ops_to_hylo = { + "add": "fetch_add", + "fadd": "fetch_add", + "sub": "fetch_sub", + "fsub": "fetch_sub", + "max": "fetch_max", + "umax": "fetch_max", + "fmax": "fetch_max", + "min": "fetch_min", + "umin": "fetch_min", + "fmin": "fetch_min", + "and": "fetch_and", + "nand": "fetch_nand", + "or": "fetch_or", + "xor": "fetch_xor", +} + +load_orderings = [ + # hylo_ordering, native_ordering + ("relaxed", "relaxed", 0), + ("acquiring", "acquire", 1), + ("sequentially_consistent", "seqcst", 4), +] + +store_orderings = [ + # hylo_ordering, native_ordering + ("relaxed", "relaxed", 0), + ("releasing", "release", 2), + ("sequentially_consistent", "seqcst", 4), +] + +update_orderings = [ + # hylo_ordering, native_ordering, value + ("relaxed", "relaxed", 0), + ("acquiring", "acquire", 1), + ("releasing", "release", 2), + ("acquiring_and_releasing", "acqrel", 3), + ("sequentially_consistent", "seqcst", 4), +] From 485db41d40e4ec1f496863230cdae5eb3f7e3f11 Mon Sep 17 00:00:00 2001 From: Lucian Radu Teodorescu Date: Thu, 2 Jan 2025 11:08:03 +0200 Subject: [PATCH 2/3] Fix typos --- .../LowLevel/Threading/AtomicOrderings.hylo | 6 +++--- .../LowLevel/Threading/PlatformAtomics.hylo | 16 ++++++++-------- .../LowLevel/Threading/PlatformAtomics.hylo.gyb | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo b/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo index 0eec39a09..442e38678 100644 --- a/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo +++ b/StandardLibrary/Sources/LowLevel/Threading/AtomicOrderings.hylo @@ -1,4 +1,4 @@ -/// Specifies the memory ordering sematics for an atomic load operation. +/// Specifies the memory ordering semantics for an atomic load operation. public type AtomicLoadOrdering: Regular { public memberwise init @@ -38,7 +38,7 @@ public extension AtomicLoadOrdering { } -/// Specifies the memory ordering sematics for an atomic store operation. +/// Specifies the memory ordering semantics for an atomic store operation. public type AtomicStoreOrdering: Regular { public memberwise init @@ -78,7 +78,7 @@ public extension AtomicStoreOrdering { } -/// Specifies the memory ordering sematics for an atomic read-modify-write (update) operation. +/// Specifies the memory ordering semantics for an atomic read-modify-write (update) operation. public type AtomicUpdateOrdering: Regular { public memberwise init diff --git a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo index 7aa5aa454..26aa82448 100644 --- a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo +++ b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo @@ -6,7 +6,7 @@ /// An atomic representation of Int. public type IntAtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: Int public memberwise init @@ -371,7 +371,7 @@ public conformance IntAtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of Int8. public type Int8AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: Int8 public memberwise init @@ -736,7 +736,7 @@ public conformance Int8AtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of Int32. public type Int32AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: Int32 public memberwise init @@ -1101,7 +1101,7 @@ public conformance Int32AtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of Int64. public type Int64AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: Int64 public memberwise init @@ -1466,7 +1466,7 @@ public conformance Int64AtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of UInt. public type UIntAtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: UInt public memberwise init @@ -1831,7 +1831,7 @@ public conformance UIntAtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of UInt8. public type UInt8AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: UInt8 public memberwise init @@ -2196,7 +2196,7 @@ public conformance UInt8AtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of UInt32. public type UInt32AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: UInt32 public memberwise init @@ -2561,7 +2561,7 @@ public conformance UInt32AtomicRepresentation: IntegerPlatformAtomic { /// An atomic representation of UInt64. public type UInt64AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: UInt64 public memberwise init diff --git a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb index c11dd2b6c..abdeda402 100644 --- a/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb +++ b/StandardLibrary/Sources/LowLevel/Threading/PlatformAtomics.hylo.gyb @@ -11,7 +11,7 @@ /// An atomic representation of ${type}. public type ${type}AtomicRepresentation: Regular { - /// The undelying value, for which we expose atomic operations. + /// The underlying value, for which we expose atomic operations. internal let value: ${type} public memberwise init From 14be838f3eb3f68851618721521e03d8a80183c5 Mon Sep 17 00:00:00 2001 From: Lucian Radu Teodorescu Date: Fri, 3 Jan 2025 14:14:56 +0200 Subject: [PATCH 3/3] Enable "output on failure" when running tests with ctest. This way, we know more about what failed, and not get just "exception". --- .github/workflows/build-and-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index a0a59e057..6a831fa6c 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -112,7 +112,7 @@ jobs: find .ninja-build -name '*.a' -delete - ctest --parallel --test-dir .ninja-build + ctest --parallel --output-on-failure --test-dir .ninja-build push: never - name: Reclaim disk space @@ -281,7 +281,7 @@ jobs: run: cmake --build hylo/.ninja-build ${{ matrix.cmake_generator == 'Xcode' && format('--config {0}', matrix.cmake_build_type) || '' }} - name: Test (CMake) - run: ctest --parallel --test-dir hylo/.ninja-build ${{ matrix.cmake_generator == 'Xcode' && format('-C {0}', matrix.cmake_build_type) || '' }} + run: ctest --parallel --output-on-failure --test-dir hylo/.ninja-build ${{ matrix.cmake_generator == 'Xcode' && format('-C {0}', matrix.cmake_build_type) || '' }} - if: ${{ matrix.use_spm }} name: Create LLVM pkgconfig file and make it findable