| 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| 2 | |
| 3 | #ifndef TARGET_ARM_VECTOR_TYPE_H |
| 4 | #define TARGET_ARM_VECTOR_TYPE_H |
| 5 | |
| 6 | /* |
| 7 | * Define a maximum sized vector register. |
| 8 | * For 32-bit, this is a 128-bit NEON/AdvSIMD register. |
| 9 | * For 64-bit, this is a 2048-bit SVE register. |
| 10 | * |
| 11 | * Note that the mapping between S, D, and Q views of the register bank |
| 12 | * differs between AArch64 and AArch32. |
| 13 | * In AArch32: |
| 14 | * Qn = regs[n].d[1]:regs[n].d[0] |
| 15 | * Dn = regs[n / 2].d[n & 1] |
| 16 | * Sn = regs[n / 4].d[n % 4 / 2], |
| 17 | * bits 31..0 for even n, and bits 63..32 for odd n |
| 18 | * (and regs[16] to regs[31] are inaccessible) |
| 19 | * In AArch64: |
| 20 | * Zn = regs[n].d[*] |
| 21 | * Qn = regs[n].d[1]:regs[n].d[0] |
| 22 | * Dn = regs[n].d[0] |
| 23 | * Sn = regs[n].d[0] bits 31..0 |
| 24 | * Hn = regs[n].d[0] bits 15..0 |
| 25 | * |
| 26 | * This corresponds to the architecturally defined mapping between |
| 27 | * the two execution states, and means we do not need to explicitly |
| 28 | * map these registers when changing states. |
| 29 | * |
| 30 | * Align the data for use with TCG host vector operations. |
| 31 | */ |
| 32 | |
| 33 | #define ARM_MAX_VQ 16 |
| 34 | |
| 35 | typedef struct ARMVectorReg { |
| 36 | uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16); |
| 37 | } ARMVectorReg; |
| 38 | |
| 39 | /* In AArch32 mode, predicate registers do not exist at all. */ |
| 40 | typedef struct ARMPredicateReg { |
| 41 | uint64_t p[DIV_ROUND_UP(2 * ARM_MAX_VQ, 8)] QEMU_ALIGNED(16); |
| 42 | } ARMPredicateReg; |
| 43 | |
| 44 | #endif |