[PATCH v2 21/50] helper-to-tcg: Add guest vector layout description

Anton Johansson via qemu development <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
Vectors are represented as arrays of host-endian blocks at least 64 bits in
size, the size of which is configurable.  Lane 0 in each block may be
placed either at the most- or least-significant bytes.

This covers a wide range of QEMU targets' vector representations.

Vector layout information is used later when mapping constant
expressions such as constant vectors, and when emitting helper functions
for performing size-changing operations.

Signed-off-by: Anton Johansson <[email protected]>
---
 .../helper-to-tcg/include/VectorLayout.hpp    | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 subprojects/helper-to-tcg/include/VectorLayout.hpp

diff --git a/subprojects/helper-to-tcg/include/VectorLayout.hpp b/subprojects/helper-to-tcg/include/VectorLayout.hpp
new file mode 100644
index 0000000000..e85f5029d5
--- /dev/null
+++ b/subprojects/helper-to-tcg/include/VectorLayout.hpp
@@ -0,0 +1,116 @@
+//
+//  Copyright(c) 2026 rev.ng Labs Srl. All Rights Reserved.
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+
+#pragma once
+
+#include <llvm/ADT/ArrayRef.h>
+#include <stddef.h>
+#include <stdint.h>
+
+// Vector Layout
+//
+// Vector layouts among QEMU guests is quite diverse, this header aims to be
+// simple but still capture a large subset of targets.
+//
+// Guest vectors are assumed to be divided into host-endian blocks of a
+// configurable size (>= 64-bit and power-of-two), with block 0 always being at
+// the lowest address.  Blocks in turn are divided into 64-bit columns which are
+// used when interfacing with QEMUs `gvec` API.
+//
+// Below is a 32-byte <32 x i8> guest vector consisting of 16-byte blocks,
+// 8-byte columns, and 1-byte lanes for each element in the vector.  Elements
+// count from 1-32 in hex to indicate their position in memory.  Note this
+// example is for a little-endian host with `LeastSignificant` lane preference
+// meaning lane 0 is at the least significant bytes of each block.
+//
+//   Guest vector <32 x i8> {1, 2, 3, ..., 32}
+//   +---------------------------------+---------------------------------+
+//   |              BLOCK 0            |              BLOCK 1            |
+//   +----------------+----------------+----------------+----------------+
+//   |    COLUMN 0    |    COLUMN 1    |    COLUMN 2    |    COLUMN 3    |
+//   |0102030405060708|090A0B0C0D0E0F10|1112131415161718|191A1B1C1D1E1F20|
+//
+//   LOW ADDRESS                                              HIGH ADDRESS
+//
+// On a big-endian host, the vector would instead be expressed in memory as
+//
+//   Guest vector <32 x i8> {1, 2, 3, ..., 32}
+//   +---------------------------------+---------------------------------+
+//   |              BLOCK 0            |              BLOCK 1            |
+//   +----------------+----------------+----------------+----------------+
+//   |    COLUMN 1    |    COLUMN 0    |    COLUMN 3    |    COLUMN 2    |
+//   |100F0E0D0C0B0A09|0807060504030201|201F1E1D1C1B1A19|1817161514131211|
+//
+//   LOW ADDRESS                                              HIGH ADDRESS
+//
+// with the column order having shifted to make sure the host-endian blocks
+// retain the same value.  Blocks are also allowed to be equal or greater in
+// size that the guest vector, at which point the entire memory view of the
+// vector would reverse when going from a little to big-endian host.
+//
+// The lane preference may also be changed to `MostSignificant` which for the
+// little-endian example places lane 0 and the highest address of block 0.
+// Note, that `MostSignificant` on little-endian and `LeastSignificant` on
+// big-endian hosts are equivalent in their memory representation, but will
+// differ in how they are emitted in C:
+//
+//   // MostSignificant, little endian
+//   uint64_t vec[] = {0x90A0B0C0D0E0F10, 0x102030405060708, ...};
+//
+//   // LeastSignificant, big endian
+//   uint64_t vec[] = {0x100F0E0D0C0B0A09, 0x807060504030201, ...};
+//
+
+enum LanePreference {
+    LeastSignificant,
+    MostSignificant,
+};
+
+struct VectorLayout {
+    bool HostBigEndian;
+    LanePreference Lane0;
+    size_t BlockBytes;
+
+    inline size_t index(bool Reverse, size_t Count, size_t I, size_t J) const {
+        if (Reverse) {
+            return Count * I + (J ^ (Count - 1));
+        } else {
+            return Count * I + J;
+        }
+    }
+
+    // Return the index into a linear array of lane L in column C
+    inline size_t indexLane(size_t LanesPerColumn, size_t C, size_t L) const {
+        const bool Reverse = (Lane0 == MostSignificant);
+        return index(Reverse, LanesPerColumn, C, L);
+    }
+
+    // Return the index into a linear array of
+    inline size_t indexBlock(size_t BlocksPerVec, size_t I) const {
+        const bool Reverse = (HostBigEndian ^ (Lane0 == MostSignificant));
+        return index(Reverse, BlocksPerVec, 0, I);
+    }
+
+    //inline uint64_t column(llvm::ArrayRef<uint64_t> Lanes) {
+    //    uint64_t Column = 0;
+    //    const size_t LanesPerColumn = 64 / ElementSize;
+    //    for (size_t L = 0; L < LanesPerColumn; ++L) {
+    //        const size_t Index = VL.indexLane(LanesPerColumn, C, L);
+    //        Column |= Ints[Index] << (ElementSize * L);
+    //    }
+    //}
+};
-- 
2.52.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.