VirtualBox

Changeset 102623 in vbox for trunk/include


Ignore:
Timestamp:
Dec 16, 2023 12:00:51 AM (17 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
160778
Message:

VMM/IEM: ARM64 version of BODY_CHECK_OPCODES, enabled two more builtins. Optimized immediate loading a little bit. bugref:10371

File:
1 edited

Legend:

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

    r102510 r102623  
    22832283typedef enum                         /* Size VR Opc */
    22842284{                                    /*     \ | /   */
    2285     kArmv8A64InstrLdStType_Mask_Size       = 0x300,
    2286     kArmv8A64InstrLdStType_Mask_VR         = 0x010,
    2287     kArmv8A64InstrLdStType_Mask_Opc        = 0x003,
    2288     kArmv8A64InstrLdStType_Shift_Size      =     8,
    2289     kArmv8A64InstrLdStType_Shift_VR        =     4,
    2290     kArmv8A64InstrLdStType_Shift_Opc       =     0,
    2291 
    2292     kArmv8A64InstrLdStType_St_Byte         = 0x000,
    2293     kArmv8A64InstrLdStType_Ld_Byte         = 0x001,
    2294     kArmv8A64InstrLdStType_Ld_SignByte64   = 0x002,
    2295     kArmv8A64InstrLdStType_Ld_SignByte32   = 0x003,
    2296 
    2297     kArmv8A64InstrLdStType_St_Half         = 0x100, /**< Half = 16-bit */
    2298     kArmv8A64InstrLdStType_Ld_Half         = 0x101, /**< Half = 16-bit */
    2299     kArmv8A64InstrLdStType_Ld_SignHalf64   = 0x102, /**< Half = 16-bit */
    2300     kArmv8A64InstrLdStType_Ld_SignHalf32   = 0x103, /**< Half = 16-bit */
    2301 
    2302     kArmv8A64InstrLdStType_St_Word         = 0x200, /**< Word = 32-bit */
    2303     kArmv8A64InstrLdStType_Ld_Word         = 0x201, /**< Word = 32-bit */
    2304     kArmv8A64InstrLdStType_Ld_SignWord64   = 0x202, /**< Word = 32-bit */
    2305 
    2306     kArmv8A64InstrLdStType_St_Dword        = 0x300, /**< Dword = 64-bit */
    2307     kArmv8A64InstrLdStType_Ld_Dword        = 0x301, /**< Dword = 64-bit */
    2308 
    2309     kArmv8A64InstrLdStType_Prefetch        = 0x302, /**< Not valid in all variations, check docs. */
    2310 
    2311     kArmv8A64InstrLdStType_St_Vr_Byte      = 0x010,
    2312     kArmv8A64InstrLdStType_Ld_Vr_Byte      = 0x011,
    2313     kArmv8A64InstrLdStType_St_Vr_128       = 0x012,
    2314     kArmv8A64InstrLdStType_Ld_Vr_128       = 0x013,
    2315 
    2316     kArmv8A64InstrLdStType_St_Vr_Half      = 0x110, /**< Half = 16-bit */
    2317     kArmv8A64InstrLdStType_Ld_Vr_Half      = 0x111, /**< Half = 16-bit */
    2318 
    2319     kArmv8A64InstrLdStType_St_Vr_Word      = 0x210, /**< Word = 32-bit */
    2320     kArmv8A64InstrLdStType_Ld_Vr_Word      = 0x211, /**< Word = 32-bit */
    2321 
    2322     kArmv8A64InstrLdStType_St_Vr_Dword     = 0x310, /**< Dword = 64-bit */
    2323     kArmv8A64InstrLdStType_Ld_Vr_Dword     = 0x311  /**< Dword = 64-bit */
     2285    kArmv8A64InstrLdStType_Mask_Size     = 0x300,
     2286    kArmv8A64InstrLdStType_Mask_VR       = 0x010,
     2287    kArmv8A64InstrLdStType_Mask_Opc      = 0x003,
     2288    kArmv8A64InstrLdStType_Shift_Size    =     8,
     2289    kArmv8A64InstrLdStType_Shift_VR      =     4,
     2290    kArmv8A64InstrLdStType_Shift_Opc     =     0,
     2291
     2292    kArmv8A64InstrLdStType_St_Byte       = 0x000,
     2293    kArmv8A64InstrLdStType_Ld_Byte       = 0x001,
     2294    kArmv8A64InstrLdStType_Ld_SignByte64 = 0x002,
     2295    kArmv8A64InstrLdStType_Ld_SignByte32 = 0x003,
     2296
     2297    kArmv8A64InstrLdStType_St_Half       = 0x100, /**< Half = 16-bit */
     2298    kArmv8A64InstrLdStType_Ld_Half       = 0x101, /**< Half = 16-bit */
     2299    kArmv8A64InstrLdStType_Ld_SignHalf64 = 0x102, /**< Half = 16-bit */
     2300    kArmv8A64InstrLdStType_Ld_SignHalf32 = 0x103, /**< Half = 16-bit */
     2301
     2302    kArmv8A64InstrLdStType_St_Word       = 0x200, /**< Word = 32-bit */
     2303    kArmv8A64InstrLdStType_Ld_Word       = 0x201, /**< Word = 32-bit */
     2304    kArmv8A64InstrLdStType_Ld_SignWord64 = 0x202, /**< Word = 32-bit */
     2305
     2306    kArmv8A64InstrLdStType_St_Dword      = 0x300, /**< Dword = 64-bit */
     2307    kArmv8A64InstrLdStType_Ld_Dword      = 0x301, /**< Dword = 64-bit */
     2308
     2309    kArmv8A64InstrLdStType_Prefetch      = 0x302, /**< Not valid in all variations, check docs. */
     2310
     2311    kArmv8A64InstrLdStType_St_Vr_Byte    = 0x010,
     2312    kArmv8A64InstrLdStType_Ld_Vr_Byte    = 0x011,
     2313    kArmv8A64InstrLdStType_St_Vr_128     = 0x012,
     2314    kArmv8A64InstrLdStType_Ld_Vr_128     = 0x013,
     2315
     2316    kArmv8A64InstrLdStType_St_Vr_Half    = 0x110, /**< Half = 16-bit */
     2317    kArmv8A64InstrLdStType_Ld_Vr_Half    = 0x111, /**< Half = 16-bit */
     2318
     2319    kArmv8A64InstrLdStType_St_Vr_Word    = 0x210, /**< Word = 32-bit */
     2320    kArmv8A64InstrLdStType_Ld_Vr_Word    = 0x211, /**< Word = 32-bit */
     2321
     2322    kArmv8A64InstrLdStType_St_Vr_Dword   = 0x310, /**< Dword = 64-bit */
     2323    kArmv8A64InstrLdStType_Ld_Vr_Dword   = 0x311  /**< Dword = 64-bit */
    23242324
    23252325} ARMV8A64INSTRLDSTTYPE;
     
    31663166         | iRegResult;
    31673167}
     3168
     3169
     3170/** Alias for sub zxr, reg, #uimm12.  */
     3171DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCmpUImm12(uint32_t iRegSrc, uint32_t uImm12Comprahend,
     3172                                                     bool f64Bit = true, bool fShift12 = false)
     3173{
     3174    return Armv8A64MkInstrAddSubUImm12(true /*fSub*/, ARMV8_A64_REG_XZR, iRegSrc, uImm12Comprahend,
     3175                                       f64Bit, true /*fSetFlags*/, fShift12);
     3176}
     3177
     3178
     3179/** ADD dst, src, #uimm12  */
     3180DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrAddUImm12(uint32_t iRegResult, uint32_t iRegSrc, uint32_t uImm12Addend,
     3181                                                     bool f64Bit = true, bool fSetFlags = false, bool fShift12 = false)
     3182{
     3183    return Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iRegResult, iRegSrc, uImm12Addend, f64Bit, fSetFlags, fShift12);
     3184}
     3185
     3186
     3187/** SUB dst, src, #uimm12  */
     3188DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrSubUImm12(uint32_t iRegResult, uint32_t iRegSrc, uint32_t uImm12Subtrahend,
     3189                                                     bool f64Bit = true, bool fSetFlags = false, bool fShift12 = false)
     3190{
     3191    return Armv8A64MkInstrAddSubUImm12(true /*fSub*/, iRegResult, iRegSrc, uImm12Subtrahend, f64Bit, fSetFlags, fShift12);
     3192}
     3193
    31683194
    31693195/**
     
    32063232         | (iRegSrc1               <<  5)
    32073233         | iRegResult;
     3234}
     3235
     3236
     3237/** Alias for sub zxr, reg1, reg2 [, LSL/LSR/ASR/ROR #xx].  */
     3238DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCmpReg(uint32_t iRegSrc1, uint32_t iRegSrc2, bool f64Bit = true, uint32_t cShift = 0,
     3239                                                  ARMV8A64INSTRSHIFT enmShift = kArmv8A64InstrShift_Lsl)
     3240{
     3241    return Armv8A64MkInstrAddSubReg(true /*fSub*/, ARMV8_A64_REG_XZR, iRegSrc1, iRegSrc2,
     3242                                    f64Bit, true /*fSetFlags*/, cShift, enmShift);
    32083243}
    32093244
     
    34253460}
    34263461
     3462/** @name  RMA64_NZCV_F_XXX - readable NZCV mask for CCMP and friends.
     3463 * @{ */
     3464#define ARMA64_NZCV_F_N0_Z0_C0_V0     UINT32_C(0x0)
     3465#define ARMA64_NZCV_F_N0_Z0_C0_V1     UINT32_C(0x1)
     3466#define ARMA64_NZCV_F_N0_Z0_C1_V0     UINT32_C(0x2)
     3467#define ARMA64_NZCV_F_N0_Z0_C1_V1     UINT32_C(0x3)
     3468#define ARMA64_NZCV_F_N0_Z1_C0_V0     UINT32_C(0x4)
     3469#define ARMA64_NZCV_F_N0_Z1_C0_V1     UINT32_C(0x5)
     3470#define ARMA64_NZCV_F_N0_Z1_C1_V0     UINT32_C(0x6)
     3471#define ARMA64_NZCV_F_N0_Z1_C1_V1     UINT32_C(0x7)
     3472
     3473#define ARMA64_NZCV_F_N1_Z0_C0_V0     UINT32_C(0x8)
     3474#define ARMA64_NZCV_F_N1_Z0_C0_V1     UINT32_C(0x9)
     3475#define ARMA64_NZCV_F_N1_Z0_C1_V0     UINT32_C(0xa)
     3476#define ARMA64_NZCV_F_N1_Z0_C1_V1     UINT32_C(0xb)
     3477#define ARMA64_NZCV_F_N1_Z1_C0_V0     UINT32_C(0xc)
     3478#define ARMA64_NZCV_F_N1_Z1_C0_V1     UINT32_C(0xd)
     3479#define ARMA64_NZCV_F_N1_Z1_C1_V0     UINT32_C(0xe)
     3480#define ARMA64_NZCV_F_N1_Z1_C1_V1     UINT32_C(0xf)
     3481/** @} */
     3482
     3483/**
     3484 * A64: Encodes CCMP or CCMN with two register operands.
     3485 *
     3486 * @returns The encoded instruction.
     3487 * @param   iRegSrc1    The 1st register. SP is NOT valid, but ZR is.
     3488 * @param   iRegSrc2    The 2nd register. SP is NOT valid, but ZR is.
     3489 * @param   fNzcv       The N, Z, C & V flags values to load if the condition
     3490 *                      does not match. See RMA64_NZCV_F_XXX.
     3491 * @param   enmCond     The condition guarding the compare.
     3492 * @param   fCCmp       Set for CCMP (default), clear for CCMN.
     3493 * @param   f64Bit      true for 64-bit GRPs (default), false for 32-bit GPRs.
     3494 */
     3495DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmpCmnReg(uint32_t iRegSrc1, uint32_t iRegSrc2, uint32_t fNzcv,
     3496                                                      ARMV8INSTRCOND enmCond, bool fCCmp = true, bool f64Bit = true)
     3497{
     3498    Assert(iRegSrc1 < 32); Assert(iRegSrc2 < 32); Assert(fNzcv < 16);
     3499
     3500    return ((uint32_t)f64Bit       << 31)
     3501         | ((uint32_t)fCCmp        << 30)
     3502         | UINT32_C(0x3a400000)
     3503         | (iRegSrc2               << 16)
     3504         | ((uint32_t)enmCond      << 12)
     3505         | (iRegSrc1               <<  5)
     3506         | fNzcv;
     3507}
     3508
     3509/** CCMP w/ reg. */
     3510DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmpReg(uint32_t iRegSrc1, uint32_t iRegSrc2, uint32_t fNzcv,
     3511                                                   ARMV8INSTRCOND enmCond, bool f64Bit = true)
     3512{
     3513    return Armv8A64MkInstrCCmpCmnReg(iRegSrc1, iRegSrc2, fNzcv, enmCond, true /*fCCmp*/, f64Bit);
     3514}
     3515
     3516
     3517/** CCMN w/ reg. */
     3518DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmnReg(uint32_t iRegSrc1, uint32_t iRegSrc2, uint32_t fNzcv,
     3519                                                   ARMV8INSTRCOND enmCond, bool f64Bit = true)
     3520{
     3521    return Armv8A64MkInstrCCmpCmnReg(iRegSrc1, iRegSrc2, fNzcv, enmCond, false /*fCCmp*/, f64Bit);
     3522}
     3523
     3524
     3525/**
     3526 * A64: Encodes CCMP or CCMN with register and 5-bit immediate.
     3527 *
     3528 * @returns The encoded instruction.
     3529 * @param   iRegSrc     The register. SP is NOT valid, but ZR is.
     3530 * @param   uImm5       The immediate, to compare iRegSrc with.
     3531 * @param   fNzcv       The N, Z, C & V flags values to load if the condition
     3532 *                      does not match. See RMA64_NZCV_F_XXX.
     3533 * @param   enmCond     The condition guarding the compare.
     3534 * @param   fCCmp       Set for CCMP (default), clear for CCMN.
     3535 * @param   f64Bit      true for 64-bit GRPs (default), false for 32-bit GPRs.
     3536 */
     3537DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmpCmnImm(uint32_t iRegSrc, uint32_t uImm5, uint32_t fNzcv, ARMV8INSTRCOND enmCond,
     3538                                                      bool fCCmp = true, bool f64Bit = true)
     3539{
     3540    Assert(iRegSrc < 32); Assert(uImm5 < 32); Assert(fNzcv < 16);
     3541
     3542    return ((uint32_t)f64Bit       << 31)
     3543         | ((uint32_t)fCCmp        << 30)
     3544         | UINT32_C(0x3a400800)
     3545         | (uImm5                  << 16)
     3546         | ((uint32_t)enmCond      << 12)
     3547         | (iRegSrc                <<  5)
     3548         | fNzcv;
     3549}
     3550
     3551/** CCMP w/ immediate. */
     3552DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmpImm(uint32_t iRegSrc, uint32_t uImm5, uint32_t fNzcv,
     3553                                                   ARMV8INSTRCOND enmCond, bool f64Bit = true)
     3554{
     3555    return Armv8A64MkInstrCCmpCmnImm(iRegSrc, uImm5, fNzcv, enmCond, true /*fCCmp*/, f64Bit);
     3556}
     3557
     3558
     3559/** CCMN w/ immediate. */
     3560DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrCCmnImm(uint32_t iRegSrc, uint32_t uImm5, uint32_t fNzcv,
     3561                                                   ARMV8INSTRCOND enmCond, bool f64Bit = true)
     3562{
     3563    return Armv8A64MkInstrCCmpCmnImm(iRegSrc, uImm5, fNzcv, enmCond, false /*fCCmp*/, f64Bit);
     3564}
    34273565
    34283566/** @} */
Note: See TracChangeset for help on using the changeset viewer.

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