VirtualBox

Changeset 103715 in vbox for trunk/include/iprt/armv8.h


Ignore:
Timestamp:
Mar 6, 2024 7:48:11 PM (9 months ago)
Author:
vboxsync
Message:

include/iprt/armv8.h: Some NEON/SIMD helpers, bugref:10614

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/armv8.h

    r103691 r103715  
    131131#define ARMV8_A64_REG_W29                           ARMV8_A64_REG_X29
    132132#define ARMV8_A64_REG_W30                           ARMV8_A64_REG_X30
     133/** @} */
     134
     135/** @name The AArch64 NEON scalar register encoding.
     136 * @{ */
     137#define ARMV8_A64_REG_Q0                            0
     138#define ARMV8_A64_REG_Q1                            1
     139#define ARMV8_A64_REG_Q2                            2
     140#define ARMV8_A64_REG_Q3                            3
     141#define ARMV8_A64_REG_Q4                            4
     142#define ARMV8_A64_REG_Q5                            5
     143#define ARMV8_A64_REG_Q6                            6
     144#define ARMV8_A64_REG_Q7                            7
     145#define ARMV8_A64_REG_Q8                            8
     146#define ARMV8_A64_REG_Q9                            9
     147#define ARMV8_A64_REG_Q10                           10
     148#define ARMV8_A64_REG_Q11                           11
     149#define ARMV8_A64_REG_Q12                           12
     150#define ARMV8_A64_REG_Q13                           13
     151#define ARMV8_A64_REG_Q14                           14
     152#define ARMV8_A64_REG_Q15                           15
     153#define ARMV8_A64_REG_Q16                           16
     154#define ARMV8_A64_REG_Q17                           17
     155#define ARMV8_A64_REG_Q18                           18
     156#define ARMV8_A64_REG_Q19                           19
     157#define ARMV8_A64_REG_Q20                           20
     158#define ARMV8_A64_REG_Q21                           21
     159#define ARMV8_A64_REG_Q22                           22
     160#define ARMV8_A64_REG_Q23                           23
     161#define ARMV8_A64_REG_Q24                           24
     162#define ARMV8_A64_REG_Q25                           25
     163#define ARMV8_A64_REG_Q26                           26
     164#define ARMV8_A64_REG_Q27                           27
     165#define ARMV8_A64_REG_Q28                           28
     166#define ARMV8_A64_REG_Q29                           29
     167#define ARMV8_A64_REG_Q30                           30
     168#define ARMV8_A64_REG_Q31                           31
     169/** @} */
     170
     171/** @name The AArch64 NEON vector register encoding.
     172 * @{ */
     173#define ARMV8_A64_REG_V0                            ARMV8_A64_REG_Q0
     174#define ARMV8_A64_REG_V1                            ARMV8_A64_REG_Q0
     175#define ARMV8_A64_REG_V2                            ARMV8_A64_REG_Q0
     176#define ARMV8_A64_REG_V3                            ARMV8_A64_REG_Q0
     177#define ARMV8_A64_REG_V4                            ARMV8_A64_REG_Q0
     178#define ARMV8_A64_REG_V5                            ARMV8_A64_REG_Q0
     179#define ARMV8_A64_REG_V6                            ARMV8_A64_REG_Q0
     180#define ARMV8_A64_REG_V7                            ARMV8_A64_REG_Q0
     181#define ARMV8_A64_REG_V8                            ARMV8_A64_REG_Q8
     182#define ARMV8_A64_REG_V9                            ARMV8_A64_REG_Q9
     183#define ARMV8_A64_REG_V10                           ARMV8_A64_REG_Q10
     184#define ARMV8_A64_REG_V11                           ARMV8_A64_REG_Q11
     185#define ARMV8_A64_REG_V12                           ARMV8_A64_REG_Q12
     186#define ARMV8_A64_REG_V13                           ARMV8_A64_REG_Q13
     187#define ARMV8_A64_REG_V14                           ARMV8_A64_REG_Q14
     188#define ARMV8_A64_REG_V15                           ARMV8_A64_REG_Q15
     189#define ARMV8_A64_REG_V16                           ARMV8_A64_REG_Q16
     190#define ARMV8_A64_REG_V17                           ARMV8_A64_REG_Q17
     191#define ARMV8_A64_REG_V18                           ARMV8_A64_REG_Q18
     192#define ARMV8_A64_REG_V19                           ARMV8_A64_REG_Q19
     193#define ARMV8_A64_REG_V20                           ARMV8_A64_REG_Q20
     194#define ARMV8_A64_REG_V21                           ARMV8_A64_REG_Q21
     195#define ARMV8_A64_REG_V22                           ARMV8_A64_REG_Q22
     196#define ARMV8_A64_REG_V23                           ARMV8_A64_REG_Q23
     197#define ARMV8_A64_REG_V24                           ARMV8_A64_REG_Q24
     198#define ARMV8_A64_REG_V25                           ARMV8_A64_REG_Q25
     199#define ARMV8_A64_REG_V26                           ARMV8_A64_REG_Q26
     200#define ARMV8_A64_REG_V27                           ARMV8_A64_REG_Q27
     201#define ARMV8_A64_REG_V28                           ARMV8_A64_REG_Q28
     202#define ARMV8_A64_REG_V29                           ARMV8_A64_REG_Q29
     203#define ARMV8_A64_REG_V30                           ARMV8_A64_REG_Q30
     204#define ARMV8_A64_REG_V31                           ARMV8_A64_REG_Q31
    133205/** @} */
    134206
     
    39444016/** @} */
    39454017
     4018
     4019/** @defgroup grp_rt_armv8_mkinstr_vec   Vector Instruction Encoding Helpers
     4020 * @ingroup grp_rt_armv8_mkinstr
     4021 *
     4022 * A few inlined functions and macros for assisting in encoding common ARMv8
     4023 * Neon/SIMD instructions.
     4024 *
     4025 * @{ */
     4026
     4027/**
     4028 * A64: Encodes ORR (vector, register).
     4029 *
     4030 * @returns The encoded instruction.
     4031 * @param   iVecRegDst  The vector register to put the result into.
     4032 * @param   iVecRegSrc1 The 1st source register.
     4033 * @param   iVecRegSrc2 The 2nd source register.
     4034 * @param   f128Bit     Flag whether this operates on the full 128-bit (true, default) of the vector register
     4035 *                      or just the low 64-bit (false).
     4036 */
     4037DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrOrr(uint32_t iVecRegDst, uint32_t iVecRegSrc1, uint32_t iVecRegSrc2,
     4038                                                  bool f128Bit = true)
     4039{
     4040    Assert(iVecRegDst < 32); Assert(iVecRegSrc1 < 32); Assert(iVecRegSrc2 < 32);
     4041
     4042    return UINT32_C(0x0ea01c00)
     4043         | ((uint32_t)f128Bit << 30)
     4044         | (iVecRegSrc2 << 16)
     4045         | (iVecRegSrc1 << 5)
     4046         | iVecRegDst;
     4047}
     4048
     4049
     4050/**
     4051 * A64: Encodes EOR (vector, register).
     4052 *
     4053 * @returns The encoded instruction.
     4054 * @param   iVecRegDst  The vector register to put the result into.
     4055 * @param   iVecRegSrc1 The 1st source register.
     4056 * @param   iVecRegSrc2 The 2nd source register.
     4057 * @param   f128Bit     Flag whether this operates on the full 128-bit (true, default) of the vector register
     4058 *                      or just the low 64-bit (false).
     4059 */
     4060DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrEor(uint32_t iVecRegDst, uint32_t iVecRegSrc1, uint32_t iVecRegSrc2,
     4061                                                  bool f128Bit = true)
     4062{
     4063    Assert(iVecRegDst < 32); Assert(iVecRegSrc1 < 32); Assert(iVecRegSrc2 < 32);
     4064
     4065    return UINT32_C(0x2e201c00)
     4066         | ((uint32_t)f128Bit << 30)
     4067         | (iVecRegSrc2 << 16)
     4068         | (iVecRegSrc1 << 5)
     4069         | iVecRegDst;
     4070}
     4071
     4072
     4073/** Armv8 UMOV vector element size.    */
     4074typedef enum ARMV8INSTRUMOVSZ
     4075{
     4076    kArmv8InstrUmovSz_U8  = 0, /**< Byte. */
     4077    kArmv8InstrUmovSz_U16 = 1, /**< Halfword. */
     4078    kArmv8InstrUmovSz_U32 = 2, /**< 32-bit. */
     4079    kArmv8InstrUmovSz_U64 = 3, /**< 64-bit (only valid when the destination is a 64-bit register. */
     4080} ARMV8INSTRUMOVSZ;
     4081
     4082
     4083/**
     4084 * A64: Encodes UMOV (vector, register).
     4085 *
     4086 * @returns The encoded instruction.
     4087 * @param   iRegDst     The register to put the result into.
     4088 * @param   iVecRegSrc  The vector source register.
     4089 * @param   idxElem     The element index.
     4090 * @param   enmSz       Element size of the source evctor register.
     4091 * @param   fDst64Bit   Flag whether the destination register is 64-bit (true) or 32-bit (false).
     4092 */
     4093DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrUmov(uint32_t iRegDst, uint32_t iVecRegSrc, uint8_t idxElem,
     4094                                                   ARMV8INSTRUMOVSZ enmSz = kArmv8InstrUmovSz_U64, bool fDst64Bit = true)
     4095{
     4096    Assert(iRegDst < 32); Assert(iVecRegSrc < 32);
     4097    Assert((fDst64Bit && enmSz == kArmv8InstrUmovSz_U64) || (!fDst64Bit && enmSz != kArmv8InstrUmovSz_U64));
     4098    Assert(   (enmSz == kArmv8InstrUmovSz_U8 && idxElem < 16)
     4099           || (enmSz == kArmv8InstrUmovSz_U16 && idxElem < 8)
     4100           || (enmSz == kArmv8InstrUmovSz_U32 && idxElem < 4)
     4101           || (enmSz == kArmv8InstrUmovSz_U64 && idxElem < 2));
     4102
     4103    return UINT32_C(0x0e003c00)
     4104         | ((uint32_t)fDst64Bit << 30)
     4105         | ((uint32_t)idxElem << enmSz)
     4106         | (RT_BIT_32(enmSz) << 16)
     4107         | (iVecRegSrc << 5)
     4108         | iRegDst;
     4109}
     4110
     4111
     4112/** Armv8 vector compare to zero vector element size.    */
     4113typedef enum ARMV8INSTRVECCMPZEROSZ
     4114{
     4115    kArmv8InstrCmpZeroSz_S8  = 0, /**< Byte. */
     4116    kArmv8InstrCmpZeroSz_S16 = 1, /**< Halfword. */
     4117    kArmv8InstrCmpZeroSz_S32 = 2, /**< 32-bit. */
     4118    kArmv8InstrCmpZeroSz_S64 = 3, /**< 64-bit. */
     4119} ARMV8INSTRVECCMPZEROSZ;
     4120
     4121
     4122/** Armv8 vector compare to zero vector operation.    */
     4123typedef enum ARMV8INSTRVECCMPZEROOP
     4124{
     4125    kArmv8InstrCmpZeroOp_Gt = 0,                            /**< Greater than. */
     4126    kArmv8InstrCmpZeroOp_Ge = RT_BIT_32(29),                /**< Greater than or equal to. */
     4127    kArmv8InstrCmpZeroOp_Eq = RT_BIT_32(12),                /**< Equal to. */
     4128    kArmv8InstrCmpZeroOp_Le = RT_BIT_32(29) | RT_BIT_32(12) /**< Lower than or equal to. */
     4129} ARMV8INSTRVECCMPZEROOP;
     4130
     4131
     4132/**
     4133 * A64: Encodes UMOV (vector, register).
     4134 *
     4135 * @returns The encoded instruction.
     4136 * @param   iRegDst     The register to put the result into.
     4137 * @param   iVecRegSrc  The vector source register.
     4138 * @param   idxElem     The element index.
     4139 * @param   fDst64Bit   Flag whether the destination register is 64-bit (true) or 32-bit (false).
     4140 */
     4141DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrCmpToZero(uint32_t iVecRegDst, uint32_t iVecRegSrc, ARMV8INSTRVECCMPZEROSZ enmSz,
     4142                                                        ARMV8INSTRVECCMPZEROOP enmOp)
     4143{
     4144    Assert(iVecRegDst < 32); Assert(iVecRegSrc < 32);
     4145
     4146    return UINT32_C(0x5e208800)
     4147         | ((uint32_t)enmSz << 22)
     4148         | (RT_BIT_32(enmSz) << 16)
     4149         | (iVecRegSrc << 5)
     4150         | iVecRegDst
     4151         | (uint32_t)enmOp;
     4152}
     4153
     4154
     4155/**
     4156 * A64: Encodes CNT (vector, register).
     4157 *
     4158 * @returns The encoded instruction.
     4159 * @param   iRegDst     The register to put the result into.
     4160 * @param   iVecRegSrc  The vector source register.
     4161 * @param   f128Bit     Flag whether this operates on the full 128-bit (true, default) of the vector register
     4162 *                      or just the low 64-bit (false).
     4163 */
     4164DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrCnt(uint32_t iVecRegDst, uint32_t iVecRegSrc, bool f128Bit = true)
     4165{
     4166    Assert(iVecRegDst < 32); Assert(iVecRegSrc < 32);
     4167
     4168    return UINT32_C(0x0e205800)
     4169         | ((uint32_t)f128Bit << 30)
     4170         | (iVecRegSrc << 5)
     4171         | iVecRegDst;
     4172}
     4173
     4174
     4175/** @} */
     4176
    39464177#endif /* !dtrace && __cplusplus */
    39474178
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette