[Lldb-commits] [lldb] [lldb][AArch64] Add release notes and documentation for SME (PR #66767)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 6 06:36:41 PDT 2023


https://github.com/DavidSpickett updated https://github.com/llvm/llvm-project/pull/66767

>From 705251d8ecbed546f46a5929a298ad88c70cc330 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Tue, 22 Aug 2023 11:12:23 +0100
Subject: [PATCH 1/2] [lldb][AArch64] Add release notes and documentation for
 SME

This adds a release note for all the SME support now in LLDB
and a page where I have documented the user experience (for want
of a better term) when using SVE and SME.

This includes things like which mode transitions can or cannot
be triggered from within LLDB. I hope this will serve to A: document
what I've implemented and B: be a user's guide to these extensions.

(though it is not a design document, read the commits and code
for that sort of detail)
---
 lldb/docs/index.rst             |   1 +
 lldb/docs/use/aarch64-linux.rst | 190 ++++++++++++++++++++++++++++++++
 llvm/docs/ReleaseNotes.rst      |   4 +
 3 files changed, 195 insertions(+)
 create mode 100644 lldb/docs/use/aarch64-linux.rst

diff --git a/lldb/docs/index.rst b/lldb/docs/index.rst
index 2eb57cefbd883ea..2fff25b27b974ea 100644
--- a/lldb/docs/index.rst
+++ b/lldb/docs/index.rst
@@ -125,6 +125,7 @@ interesting areas to contribute to lldb.
    use/qemu-testing
    use/intel_pt
    use/ondemand
+   use/aarch64-linux
    use/troubleshooting
    use/links
    Man Page <man/lldb>
diff --git a/lldb/docs/use/aarch64-linux.rst b/lldb/docs/use/aarch64-linux.rst
new file mode 100644
index 000000000000000..850a5e5a5837cda
--- /dev/null
+++ b/lldb/docs/use/aarch64-linux.rst
@@ -0,0 +1,190 @@
+Using LLDB On AArch64 Linux
+===========================
+
+This page explains the details of debugging certain AArch64 extensions using
+LLDB. If something is not mentioned here, it likely works as you would expect.
+
+This is not a replacement for ptrace and Linux Kernel documentation. This covers
+how LLDB has chosen to use those things and how that effects your experience as
+a user.
+
+Scalable Vector Extension (SVE)
+-------------------------------
+
+See `here <https://developer.arm.com/Architectures/Scalable%20Vector%20Extensions>`__
+to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sve.html>`__
+for the Linux Kernel's handling of it.
+
+In LLDB you will be able to see the following new registers:
+
+* ``z0-z31`` vector registers, each one has size equal to the vector length.
+* ``p0-p15`` predicate registers, each one containing 1 bit per byte in the vector
+  length. Making each one vector length / 8 sized.
+* ``ffr`` the first fault register, same size as a predicate register.
+* ``vg``, the vector length in "granules". Each granule is 8 bytes.
+
+.. code-block::
+
+       Scalable Vector Extension Registers:
+             vg = 0x0000000000000002
+             z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
+           <...>
+             p0 = {0xff 0xff}
+           <...>
+            ffr = {0xff 0xff}
+
+The example above has a vector length of 16 bytes. Within LLDB you will always
+see "vg" as in the ``vg`` register, which is 2 in this case (8*2 = 16).
+Elsewhere you may see "vq" which is the vector length in quadwords (16 bytes)
+elsewhere. Where you see "vl", it is in bytes.
+
+Changing the Vector Length
+..........................
+
+While you can count the size of a P or Z register, it is intended that ``vg`` be
+used to find the current vector length.
+
+vg can be written. Writing the current vector length changes nothing. If you
+increase the vector length, the registers will likely be reset to 0. If you
+decrease it, LLDB will truncate the Z registers but everything else will be reset
+to 0.
+
+Generally you should not assume that SVE state after changing the vector length
+is in any way the same as it was previously. If you need to do it, do it before
+a function's first use of SVE.
+
+Z Register Presentation
+.......................
+
+LLDB makes no attempt to predict how an SVE Z register will be used. Even if the
+next SVE instruction (which may some distance away) would use, for example, 32
+bit elements, LLDB prints ``z0`` as single bytes.
+
+If you know what format you are going to use, give a format option::
+
+  (lldb) register read z0 -f uint32_t[]
+      z0 = {0x01010101 0x01010101 0x01010101 0x01010101}
+
+FPSIMD and SVE Modes
+....................
+
+Prior to the debugee's first use of SVE, it is in what the Linux Kernel terms
+SIMD mode. Only the FPU is being used. In this state LLDB will still show the
+SVE registers however the values are simply the FPU values zero extended up to
+the vector length.
+
+On first access to SVE, the process goes into SVE mode. Now the Z values are
+in the real Z registers.
+
+You can also trigger this with LLDB by writing to an SVE register. Note that
+there is no way to undo this change from within LLDB. However, the debugee
+itself could do something to end up back in SIMD mode.
+
+Expression evaluation
+.....................
+
+If you evaluate an expression, all SVE state is saved prior to, and restored
+after the expression has been evaluated. Including the register values and
+vector length.
+
+Scalable Matrix Extension (SME)
+-------------------------------
+
+See `here <https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture>`__
+to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sme.html>`__
+for the Linux Kernel's handling of it.
+
+SME adds a "Streaming Mode" to SVE. This mode has its own vector length.
+
+In LLDB you will see the following new registers:
+
+* ``tpidr2``, an extra per thread pointer reserved for use by the SME ABI.
+  This is not scalable, just pointer sized aka 64 bit.
+* ``z0-z31`` streaming SVE registers. These have the same names as the
+  non-streaming registers and therefore you will only see the active set in
+  LLDB. You cannot read or write the inactive mode's registers. Their size
+  is the same as the streaming vector length.
+* ``za`` the Array Storage register. The "Matrix" part of "Scalable Matrix
+  Extension". This is a square made up of rows of length equal to the streaming
+  vector length (svl). Meaning that the total size is svl * svl.
+* ``svg`` the vector length in granules. This acts the same as ``vg`` for SVE.
+  Except that where ``vg`` shows the length for the active mode, ``svg`` will
+  always show the streaming vector length, even in non-streaming mode. This
+  register is read only.
+* ``svcr`` the Streaming Vector Control Register. This is actually a pseduo
+  register but it matches the content of the architecturaly defined ``SVCR``.
+  This is the register you should use to check whether streaming mode and/or
+  ``za`` is active. This register is read only.
+
+In the example below, the streaming vector length is 16 bytes::
+
+  Scalable Vector Extension Registers:
+        vg = 0x0000000000000002
+        z0 = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
+        <...>
+        p0 = {0xff 0xff}
+        <...>
+       ffr = {0xff 0xff}
+
+  <...>
+
+  Thread Local Storage Registers:
+       tpidr = 0x0000fffff7ff4320
+      tpidr2 = 0x1122334455667788
+
+  Scalable Matrix Array Storage Registers:
+          za = {0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 <...> }
+
+  Scalable Matrix Extension Registers:
+         svg = 0x0000000000000002
+        svcr = 0x0000000000000003
+
+Note that ``svcr`` bit 1 is set meaning we are in streaming mode. Therefore
+``svg`` and ``vg`` show the same value.
+
+Changing the Streaming Vector Length
+....................................
+
+To reduce complexity for LLDB, ``svg`` is read only. This means that you can
+only change the streaming vector length using LLDB when the debugee is in
+streaming mode.
+
+As for non-streaming SVE, doing so will essentially make the content of the SVE
+registers undefined. It will also disable ZA, which follows what the Linux
+Kernel does.
+
+Inactive ZA Handling
+....................
+
+LLDB does not handle registers that can come and go at runtime (SVE changes
+size but it does not dissappear). Therefore when ``za`` is not enabled, LLDB
+will return a block of 0s instead. This block will match the expected size of
+``za``::
+
+  (lldb) register read za svg svcr
+      za = {0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 <...> }
+     svg = 0x0000000000000002
+    svcr = 0x0000000000000001
+
+Note that ``svcr`` bit 2 is not set, meaning ``za`` is inactive.
+
+If you were to write to ``za`` from LLDB, ``za`` will be made active. There is
+no way from within LLDB to reverse this change. As for changing the vector
+length, the debugee could still do something that would disable ``za`` again.
+
+If you want to know whether ``za`` is active or not, refer to bit 2 of the
+``svcr`` register.
+
+ZA Register Presentation
+........................
+
+As for SVE, LLDB does not know how you will use ``za``. At any given time an
+instruction could use any number of subsets of it. Therefore LLDB will show
+``za`` as one large vector of individual bytes.
+
+Expression evaluation
+.....................
+
+The mode (streaming or non-streaming), streaming vector length and ZA state will
+be restored after expression evaluation. On top of all the things saved for SVE
+in general.
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 660bb4e70a5a707..d7bca9540ec6a08 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -186,6 +186,10 @@ Changes to LLDB
 * Methods in SBHostOS related to threads have had their implementations
   removed. These methods will return a value indicating failure.
 
+* LLDB now supports debugging the Scalable Matrix Extension (SME) on AArch64
+  Linux for both running processes and core files. For details refer to the
+  `AArch64 Linux documentation <https://lldb.llvm.org/use/aarch64-linux.html>`_.
+
 Changes to Sanitizers
 ---------------------
 * HWASan now defaults to detecting use-after-scope bugs.

>From dbc6963addddd8150d7c158a82b355e6282367c8 Mon Sep 17 00:00:00 2001
From: David Spickett <david.spickett at linaro.org>
Date: Fri, 6 Oct 2023 14:36:21 +0100
Subject: [PATCH 2/2] Address comments

---
 lldb/docs/use/aarch64-linux.rst | 74 ++++++++++++++++++++-------------
 1 file changed, 44 insertions(+), 30 deletions(-)

diff --git a/lldb/docs/use/aarch64-linux.rst b/lldb/docs/use/aarch64-linux.rst
index 850a5e5a5837cda..707087a9bd72ea2 100644
--- a/lldb/docs/use/aarch64-linux.rst
+++ b/lldb/docs/use/aarch64-linux.rst
@@ -35,30 +35,32 @@ In LLDB you will be able to see the following new registers:
 
 The example above has a vector length of 16 bytes. Within LLDB you will always
 see "vg" as in the ``vg`` register, which is 2 in this case (8*2 = 16).
-Elsewhere you may see "vq" which is the vector length in quadwords (16 bytes)
-elsewhere. Where you see "vl", it is in bytes.
-
-Changing the Vector Length
-..........................
+Elsewhere in kernel code or applications, you may see "vq" which is the vector
+length in quadwords (16 bytes). Where you see "vl", it is in bytes.
 
 While you can count the size of a P or Z register, it is intended that ``vg`` be
 used to find the current vector length.
 
-vg can be written. Writing the current vector length changes nothing. If you
-increase the vector length, the registers will likely be reset to 0. If you
-decrease it, LLDB will truncate the Z registers but everything else will be reset
-to 0.
+Changing the Vector Length
+..........................
+
+The ``vg`` register can be written during a debug session. Writing the current
+vector length changes nothing. If you increase the vector length, the registers
+will likely be reset to 0. If you decrease it, LLDB will truncate the Z
+registers but everything else will be reset to 0.
 
-Generally you should not assume that SVE state after changing the vector length
-is in any way the same as it was previously. If you need to do it, do it before
-a function's first use of SVE.
+You should not assume that SVE state after changing the vector length is in any
+way the same as it was previously. Whether that is done from within the
+debuggee, or by LLDB. If you need to change the vector length, do so before a
+function's first use of SVE.
 
 Z Register Presentation
 .......................
 
-LLDB makes no attempt to predict how an SVE Z register will be used. Even if the
-next SVE instruction (which may some distance away) would use, for example, 32
-bit elements, LLDB prints ``z0`` as single bytes.
+LLDB makes no attempt to predict how SVE Z registers will be used. Since LLDB
+does not know what sort of elements future instructions will interpret the
+register as. It therefore does not change the visualisation of the register
+and always defaults to showing a vector of byte sized elements.
 
 If you know what format you are going to use, give a format option::
 
@@ -94,7 +96,8 @@ See `here <https://community.arm.com/arm-community-blogs/b/architectures-and-pro
 to learn about the extension and `here <https://kernel.org/doc/html/latest/arch/arm64/sme.html>`__
 for the Linux Kernel's handling of it.
 
-SME adds a "Streaming Mode" to SVE. This mode has its own vector length.
+SME adds a "Streaming Mode" to SVE, and this mode has its own vector length
+known as the "Streaming Vector Length".
 
 In LLDB you will see the following new registers:
 
@@ -107,16 +110,27 @@ In LLDB you will see the following new registers:
 * ``za`` the Array Storage register. The "Matrix" part of "Scalable Matrix
   Extension". This is a square made up of rows of length equal to the streaming
   vector length (svl). Meaning that the total size is svl * svl.
-* ``svg`` the vector length in granules. This acts the same as ``vg`` for SVE.
-  Except that where ``vg`` shows the length for the active mode, ``svg`` will
-  always show the streaming vector length, even in non-streaming mode. This
-  register is read only.
 * ``svcr`` the Streaming Vector Control Register. This is actually a pseduo
   register but it matches the content of the architecturaly defined ``SVCR``.
   This is the register you should use to check whether streaming mode and/or
   ``za`` is active. This register is read only.
+* ``svg`` the streaming vector length in granules. This value is not connected
+  to the vector length of non-streaming mode and may change independently. This
+  register is read only.
+
+.. note::
+  While in non-streaming mode, the ``vg`` register shows the non-streaming
+  vector length, and the ``svg`` register shows the streaming vector length.
+  When in streaming mode, both ``vg`` and ``svg`` show the streaming mode vector
+  length. Therefore it is not possible at this time to read the non-streaming
+  vector length within LLDB, while in streaming mode. This is a limitation of
+  the LLDB implementation not the architecture, which stores both lengths
+  independently.
 
-In the example below, the streaming vector length is 16 bytes::
+In the example below, the streaming vector length is 16 bytes and we are in
+streaming mode. Note that bits 0 and 1 of ``svcr`` are set, indicating that we
+are in streaming mode and ZA is active. ``vg`` and ``svg`` report the same value
+as ``vg`` is showing the streaming mode vector length::
 
   Scalable Vector Extension Registers:
         vg = 0x0000000000000002
@@ -139,9 +153,6 @@ In the example below, the streaming vector length is 16 bytes::
          svg = 0x0000000000000002
         svcr = 0x0000000000000003
 
-Note that ``svcr`` bit 1 is set meaning we are in streaming mode. Therefore
-``svg`` and ``vg`` show the same value.
-
 Changing the Streaming Vector Length
 ....................................
 
@@ -153,8 +164,8 @@ As for non-streaming SVE, doing so will essentially make the content of the SVE
 registers undefined. It will also disable ZA, which follows what the Linux
 Kernel does.
 
-Inactive ZA Handling
-....................
+Visibility of an Inactive ZA Register
+.....................................
 
 LLDB does not handle registers that can come and go at runtime (SVE changes
 size but it does not dissappear). Therefore when ``za`` is not enabled, LLDB
@@ -173,14 +184,17 @@ no way from within LLDB to reverse this change. As for changing the vector
 length, the debugee could still do something that would disable ``za`` again.
 
 If you want to know whether ``za`` is active or not, refer to bit 2 of the
-``svcr`` register.
+``svcr`` register, otherwise known as ``SVCR.ZA``.
 
 ZA Register Presentation
 ........................
 
-As for SVE, LLDB does not know how you will use ``za``. At any given time an
-instruction could use any number of subsets of it. Therefore LLDB will show
-``za`` as one large vector of individual bytes.
+As for SVE, LLDB does not know how the debugee will use ``za``, and therefore
+does not know how it would be best to display it. At any time any given
+instrucion could interpret its contents as many kinds and sizes of data.
+
+So LLDB will default to showing  ``za`` as one large vector of individual bytes.
+You can override this with a format option (see the SVE example above).
 
 Expression evaluation
 .....................



More information about the lldb-commits mailing list