DynamoRIO / DynamoRIO/dynamorio
Expand A64 SVE scatter/gather memory access instructions
- Dominant language
- C
- Stars
- 3.2k
- Forks
- 629
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 30
Description
ARM has a rich set of SVE instructions[1]. For clients that need to instrument memrefs (e.g. drcachesim), we need to expand them to scalar loads and stores, like what we did for x86 scatter/gather in #2985. These instructions have many variants; I'm summarising my understanding below. [1] and the Scalable Vector Extension of the Arm manual[2] have a more detailed discussion.
There are multiple ways in which the memory address can be specified. These are all predicated loads/stores, meaning that an element may be active or inactive, based on special predicate registers. They have either the `LD1*` or `ST1*` prefix
- Scalar + immediate: For contiguous access. Memory address is generated by a 64-bit scalar base and immediate index.
- Scalar + scalar: For contiguous access. Memory address is generated by a 64-bit scalar base and scalar index which is added to the base address.
- Scalar + vector: For possible non-contiguous access, also known as gather load/scatter store. Memory addresses are generated by a 64-bit scalar base plus vector index.
- Vector + immediate: For possible non-contiguous access, also known as gather load/scatter store. Memory addresses are generated by a vector base plus immediate index.
There are variants with different element sizes (unsigned double-word; signed and unsigned byte, halfword, word).
Faults for non-active elements are always suppressed. There are different load instruction variants based on how faults for active elements are treated: besides the usual, each of the above has a “first fault” (faults only for first active element) and “non fault” variants.
For “scalar plus scalar” and “scalar plus immediate” load instructions, there are variants that allow reading contiguous 2/3/4 elements, each to the same element number in 2/3/4 vector registers. These have LDN* or STN* prefix, where N=2/3/4.
There are also some un-predicated instructions (LDR and STR) that use the "scalar + immediate" scheme to load/store vectors or predicate registers.
The x86 scatter/gather that we handled in #2985 is the "scalar + vector" variant with regular faulting behaviour. More work will be required to adapt `drx_expand_scatter_gather` to these other variants.
For the contiguous access variants, we could model them as a single memory address with a larger size. But this is not a correct model, because each element can be active/inactive based on the predicate register, so the memory addresses that end up being accessed can be non-contiguous. It'll be correct to model them as scatter/gather, using multiple element-sized accesses.
[1]: https://developer.arm.com/documentation/ddi0596/2021-03/SVE-Instructions
[2]: https://developer.arm.com/documentation/ddi0584/latest/
Contributor guide
Research direction
Start by reading drx_expand_scatter_gather and the x86 scatter/gather work referenced in #2985, then consult the linked ARM SVE instruction manuals. Done means the listed predicated and unpredicated SVE memory variants are expanded into correct element-sized accesses, including predicate and fault behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100