DynamoRIO / DynamoRIO/dynamorio

Expand A64 SVE scatter/gather memory access instructions

Open
#5,036 3 comments 0 reactions 0 assignees View on GitHub
Component-DRTool OpSys-AArch64
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.