Try   HackMD

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.

.. 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