# ARM64 atomics assembly survey
This survey only concerns header files that are involved in atomic operations.
*commit `ae8b3a83fb9de394f609035041cd7a668fda2ab3`*
## Headers of interest
- `arch/arm64/include/asm/atomic.h` which includes
- `arch/arm64/include/asm/cmpxchg.h`
- `arch/arm64/include/asm/lse.h`
- `arch/arm64/include/asm/atomic-ll-sc.h`
- `arch/arm64/include/asm/barrier.h`
## Syntactical variants in use
### Key operand modifiers
The following translation is derived from [Rust reference on inline assembly](https://doc.rust-lang.org/stable/reference/inline-assembly.html#r-asm.template-modifiers.supported-modifiers).
#### .. on Output
- `=r`
- corresponds to Rust `lateout(reg)`
- `=&r`
- corresponds to Rust `out(reg)`
- `+&r`
- corresponds to Rust `inout(reg)`
- `=Q`
- specific to AArch64
- discard existing value in memory reference
- corresponds to Rust `latein(reg)` with *rewrite* into a memref
- Translation needs to know assembly dialect, which is Intel syntax mostly
- Let's say it is translated into `[{..}]`
- `+Q`
- specific to AArch64
- may use existing value in memory reference
- corresponds to Rust `latein(reg)` with *rewrite* into a memref
- Translation needs to know assembly dialect
#### .. on Input
- `rZ`
- This is specific to some machine like AArch64
- ... which is just `xzr`/`wzr`
- Requires rewrite into Rust dialect, in this case just replacing it with `xzr`/`wzr`
- `r`
- well... register
- one of {`I`,`J`,`K`,`L`} + `r`: See `atomic_ll_sc.h`
- This is specific to AArch64
- Modifies the size of immediate value
- There is no clear Rust equivalent
- In fact, when `Ir` or `rI` is specified, LLVM prefers to consider inserting an immediate of width `I/J/K/L` first, then a register as per `r` second
- `I` has higher precedence over `r`
- See `llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp` ...
- `TargetLowering::getConstraintPreferences` called by ...
- `TargetLowering::ComputeConstraintToUse` called by ...
- `llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp`: `SelectionDAGBuilder::visitInlineAsm` whose purpose is quite clear
- It is safe to translate it into `r`-equivalent constraint, unless benchmarks show deficiency.
### Clobbers
- *einfach nix*
- Translates to Rust `options(nomem, pure)`
- `memory`
- Rust has this by default, opt out with `options(nomem)`
- `cc` + `memory`
- `atomic_ll_sc`, e.g. `__ll_sc_atomic64_dec_if_positive`
- `cc` maps to `options(preserve_flags)`
- **we probably should add `options(nostack)`**
# Categories of C operands
## Input
- uninitized ...
- `unsigned long` temporaries with `=&r`
- counter like `v->counter` where `v` is `atomic_t*`
- `+Q`
## Output
Simple place expression really, either being pointer to a place or a variable used for return value.
# Observation
## asm blocks appears in various context
- it can be fully expanded into `static inline` functions;
- we probably already link into today with `helpers`
- it can be embedded in `do`-expression blocks, in a macro
- we can similarly materialise them, too