Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide more atomic ops #48

Closed
5 tasks done
taiki-e opened this issue Dec 4, 2022 · 1 comment · Fixed by #72
Closed
5 tasks done

Provide more atomic ops #48

taiki-e opened this issue Dec 4, 2022 · 1 comment · Fixed by #72
Labels
C-enhancement Category: A new feature or an improvement for an existing one

Comments

@taiki-e
Copy link
Owner

taiki-e commented Dec 4, 2022

The following are the atomic operations supported by the x86 lock prefix.

ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, and XCHG.

We currently do not provide corresponding operations for BTC, BTR, BTS, NEG, and NOT. 1 2

NEG and NOT don't return the previous value, but can be provided in a way like #47.

Footnotes

  1. To be exact, BTC, BTR, and BTS are available via other operations on Rust 1.65+, but LLVM only generates lock bt{s,r,c} for immediate bit offsets (as of LLVM 15). EDIT: see https://github.com/taiki-e/portable-atomic/issues/48#issuecomment-1453473831

  2. As for NOT, an equivalent is available via fetch_xor(-1i*)/fetch_xor(u*::MAX), though, LLVM does not lower it to lock not.

@taiki-e taiki-e added the C-enhancement Category: A new feature or an improvement for an existing one label Dec 4, 2022
bors bot added a commit that referenced this issue Dec 18, 2022
54: Add fetch_neg/neg/fetch_not/not r=taiki-e a=taiki-e

Part of #48

- Add `AtomicI*::{fetch_neg,neg}` and `AtomicF*::fetch_neg` methods.

  `AtomicI*::neg` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock neg`.

  Currently, optimizations by these methods (`neg`) are only guaranteed for x86.

- Add `Atomic{I,U}*::{fetch_not,not}` methods.

  `Atomic{I,U}*::not` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock not`, MSP430's `inv`.

  Currently, optimizations by these methods (`not`) are only guaranteed for x86 and MSP430.

  (Note: `AtomicBool` already has `fetch_not` and `not` methods.)


Co-authored-by: Taiki Endo <[email protected]>
bors bot added a commit that referenced this issue Dec 18, 2022
54: Add fetch_neg/neg/fetch_not/not r=taiki-e a=taiki-e

Part of #48

- Add `AtomicI*::{fetch_neg,neg}` and `AtomicF*::fetch_neg` methods.

  `AtomicI*::neg` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock neg`.

  Currently, optimizations by these methods (`neg`) are only guaranteed for x86.

- Add `Atomic{I,U}*::{fetch_not,not}` methods.

  `Atomic{I,U}*::not` are equivalent to the corresponding `fetch_*` methods, but do not return the previous value. They are intended for optimization on platforms that have atomic instructions for the corresponding operation, such as x86's `lock not`, MSP430's `inv`.

  Currently, optimizations by these methods (`not`) are only guaranteed for x86 and MSP430.

  (Note: `AtomicBool` already has `fetch_not` and `not` methods.)


Co-authored-by: Taiki Endo <[email protected]>
@taiki-e
Copy link
Owner Author

taiki-e commented Mar 3, 2023

LLVM only generates lock bt{s,r,c} for immediate bit offsets (as of LLVM 15).

Ok, I confirmed LLVM 16 generates lock bt{s,r,c} for both immediate and register bit offsets.

Section .text.case1::example::fetch_bit_set::h2f09b9d099cdaf68:

<case1::example::fetch_bit_set::h2f09b9d099cdaf68>:
   0: lock
   1: btsq	$0x3e, (%rdi)
   6: setb	%al
   9: retq

Section .text.case1::example::fetch_bit_reset::hf6782daec0285b9e:

<case1::example::fetch_bit_reset::hf6782daec0285b9e>:
   0: lock
   1: btrq	$0x3e, (%rdi)
   6: setb	%al
   9: retq

Section .text.case1::example::fetch_bit_toggle::h6562ca191492438e:

<case1::example::fetch_bit_toggle::h6562ca191492438e>:
   0: lock
   1: btcq	$0x3e, (%rdi)
   6: setb	%al
   9: retq

Section .text.case1::fetch_bit_set::h225c90620db049f0:

<case1::fetch_bit_set::h225c90620db049f0>:
   0: andl	$0x3f, %esi
   3: lock
   4: btsq	%rsi, (%rdi)
   8: setb	%al
   b: retq

Section .text.case1::fetch_bit_reset::hc81cc2390d523ce9:

<case1::fetch_bit_reset::hc81cc2390d523ce9>:
   0: andl	$0x3f, %esi
   3: lock
   4: btrq	%rsi, (%rdi)
   8: setb	%al
   b: retq

Section .text.case1::fetch_bit_toggle::h7889c81a712fcbda:

<case1::fetch_bit_toggle::h7889c81a712fcbda>:
   0: andl	$0x3f, %esi
   3: lock
   4: btcq	%rsi, (%rdi)
   8: setb	%al
   b: retq

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-enhancement Category: A new feature or an improvement for an existing one
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant