VirtualBox

Ignore:
Timestamp:
Mar 13, 2024 8:13:38 AM (11 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement native emitter for IEM_MC_BROADCAST_XREG_U64_ZX_VLMAX(), bugref:10614

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r103814 r103815  
    73967396}
    73977397
     7398
     7399/**
     7400 * Emits a vecdst = gprsrc broadcast, 64-bit.
     7401 */
     7402DECL_FORCE_INLINE(uint32_t)
     7403iemNativeEmitSimdBroadcastGprToVecRegU64Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iVecRegDst, uint8_t iGprSrc, bool f256Bit = false)
     7404{
     7405#ifdef RT_ARCH_AMD64
     7406    /** @todo If anyone has a better idea on how to do this more efficiently I'm all ears,
     7407     *        vbroadcast needs a memory operand or another xmm register to work... */
     7408
     7409    /* pinsrq vecsrc, gpr, #0 (ASSUMES SSE4.1). */
     7410    pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     7411    if (iVecRegDst >= 8 || iGprSrc >= 8)
     7412        pCodeBuf[off++] =   (iVecRegDst < 8 ? 0 : X86_OP_REX_R)
     7413                          | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     7414    pCodeBuf[off++] = 0x0f;
     7415    pCodeBuf[off++] = 0x3a;
     7416    pCodeBuf[off++] = 0x22;
     7417    pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iVecRegDst & 7, iGprSrc & 7);
     7418    pCodeBuf[off++] = 0x00;
     7419
     7420    if (f256Bit)
     7421    {
     7422        /* When broadcasting the entire ymm register we can use vbroadcastsd now. */
     7423        /* vbroadcastsd ymm, xmm (ASSUMES AVX2). */
     7424        pCodeBuf[off++] = X86_OP_VEX3;
     7425        pCodeBuf[off++] =   X86_OP_VEX3_BYTE1_X
     7426                          | (  iVecRegDst >= 8
     7427                             ? 0
     7428                             : X86_OP_VEX3_BYTE1_B | X86_OP_VEX3_BYTE1_R);
     7429        pCodeBuf[off++] = 0x7d;
     7430        pCodeBuf[off++] = 0x19;
     7431        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iVecRegDst & 7, iVecRegDst & 7);
     7432    }
     7433    else
     7434    {
     7435        /* pinsrq vecsrc, gpr, #1 (ASSUMES SSE4.1). */
     7436        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     7437        if (iVecRegDst >= 8 || iGprSrc >= 8)
     7438            pCodeBuf[off++] =   (iVecRegDst < 8 ? 0 : X86_OP_REX_R)
     7439                              | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     7440        pCodeBuf[off++] = 0x0f;
     7441        pCodeBuf[off++] = 0x3a;
     7442        pCodeBuf[off++] = 0x22;
     7443        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iVecRegDst & 7, iGprSrc & 7);
     7444        pCodeBuf[off++] = 0x01;
     7445    }
     7446#elif defined(RT_ARCH_ARM64)
     7447    /* ASSUMES that there are two adjacent 128-bit registers available for the 256-bit value. */
     7448    Assert(!(iVecRegDst & 0x1) || !f256Bit);
     7449
     7450    /* dup vecsrc, gpr */
     7451    pCodeBuf[off++] = Armv8A64MkVecInstrDup(iVecRegDst, iGprSrc, kArmv8InstrUmovInsSz_U64);
     7452    if (f256Bit)
     7453        pCodeBuf[off++] = Armv8A64MkVecInstrDup(iVecRegDst + 1, iGprSrc, kArmv8InstrUmovInsSz_U64);
     7454#else
     7455# error "port me"
     7456#endif
     7457    return off;
     7458}
     7459
     7460
     7461/**
     7462 * Emits a vecdst[x] = gprsrc broadcast, 64-bit.
     7463 */
     7464DECL_INLINE_THROW(uint32_t)
     7465iemNativeEmitSimdBroadcastGprToVecRegU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iVecRegDst, uint8_t iGprSrc, bool f256Bit = false)
     7466{
     7467#ifdef RT_ARCH_AMD64
     7468    off = iemNativeEmitSimdBroadcastGprToVecRegU64Ex(iemNativeInstrBufEnsure(pReNative, off, 14), off, iVecRegDst, iGprSrc, f256Bit);
     7469#elif defined(RT_ARCH_ARM64)
     7470    off = iemNativeEmitSimdBroadcastGprToVecRegU64Ex(iemNativeInstrBufEnsure(pReNative, off, f256Bit ? 2 : 1), off, iVecRegDst, iGprSrc, f256Bit);
     7471#else
     7472# error "port me"
     7473#endif
     7474    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     7475    return off;
     7476}
     7477
    73987478#endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */
    73997479
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