VirtualBox

Ignore:
Timestamp:
Jul 18, 2024 12:16:59 PM (9 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
164052
Message:

VMM/IEM: Implement native emitters for pmovzxbw/pmovzxwd/pmovzxdq/pmovsxbw/pmovsxwd/pmovsxdq instruction emulations, bugref:10652

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r105173 r105399  
    24422442
    24432443
     2444/**
     2445 * Common emitter for the pmov{s,z}x* instructions.
     2446 */
     2447#ifdef RT_ARCH_AMD64
     2448# define IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(a_Instr, a_fArmUnsigned, a_ArmElemSz, a_bOpcX86) \
     2449    DECL_INLINE_THROW(uint32_t) \
     2450    RT_CONCAT3(iemNativeEmit_,a_Instr,_rr_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     2451                                                uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc) \
     2452    { \
     2453        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     2454                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); \
     2455        uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc), \
     2456                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); \
     2457        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); \
     2458        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; \
     2459        if (idxSimdRegDst >= 8 || idxSimdRegSrc >= 8) \
     2460            pCodeBuf[off++] =   (idxSimdRegSrc >= 8 ? X86_OP_REX_B : 0) \
     2461                              | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0); \
     2462        pCodeBuf[off++] = 0x0f; \
     2463        pCodeBuf[off++] = 0x38; \
     2464        pCodeBuf[off++] = (a_bOpcX86); \
     2465        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, idxSimdRegSrc & 7); \
     2466        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     2467        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); \
     2468        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     2469        return off; \
     2470    } \
     2471    DECL_INLINE_THROW(uint32_t) \
     2472    RT_CONCAT3(iemNativeEmit_,a_Instr,_rv_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     2473                                                uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc) \
     2474    { \
     2475        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     2476                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); \
     2477        uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); \
     2478        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7 + 6); \
     2479        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; /* Transfer value from GPR to temporary vector register using pinsrq. */ \
     2480        pCodeBuf[off++] =   X86_OP_REX_W \
     2481                          | (IEMNATIVE_SIMD_REG_FIXED_TMP0 < 8 ? 0 : X86_OP_REX_R) \
     2482                          | (idxRegSrc < 8 ? 0 : X86_OP_REX_B); \
     2483        pCodeBuf[off++] = 0x0f; \
     2484        pCodeBuf[off++] = 0x3a; \
     2485        pCodeBuf[off++] = 0x22; \
     2486        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, IEMNATIVE_SIMD_REG_FIXED_TMP0 & 7, idxRegSrc & 7); \
     2487        pCodeBuf[off++] = 0; /* QWord */\
     2488        pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; \
     2489        if (idxSimdRegDst >= 8 || IEMNATIVE_SIMD_REG_FIXED_TMP0 >= 8) \
     2490            pCodeBuf[off++] =   (IEMNATIVE_SIMD_REG_FIXED_TMP0 >= 8 ? X86_OP_REX_B : 0) \
     2491                              | (idxSimdRegDst >= 8 ? X86_OP_REX_R : 0); \
     2492        pCodeBuf[off++] = 0x0f; \
     2493        pCodeBuf[off++] = 0x38; \
     2494        pCodeBuf[off++] = (a_bOpcX86); \
     2495        pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxSimdRegDst & 7, IEMNATIVE_SIMD_REG_FIXED_TMP0 & 7); \
     2496        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     2497        iemNativeVarRegisterRelease(pReNative, idxVarSrc); \
     2498        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     2499        return off; \
     2500    } \
     2501    typedef int ignore_semicolon
     2502#elif defined(RT_ARCH_ARM64)
     2503# define IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(a_Instr, a_fArmUnsigned, a_ArmElemSz, a_bOpcX86) \
     2504    DECL_INLINE_THROW(uint32_t) \
     2505    RT_CONCAT3(iemNativeEmit_,a_Instr,_rr_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     2506                                                uint8_t const idxSimdGstRegDst, uint8_t const idxSimdGstRegSrc) \
     2507    { \
     2508        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     2509                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); \
     2510        uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegSrc), \
     2511                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); \
     2512        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); \
     2513        pCodeBuf[off++] = Armv8A64MkVecInstrUShll(idxSimdRegDst, idxSimdRegSrc, 0, (a_ArmElemSz), (a_fArmUnsigned)); \
     2514        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     2515        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); \
     2516        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     2517        return off; \
     2518    } \
     2519    DECL_INLINE_THROW(uint32_t) \
     2520    RT_CONCAT3(iemNativeEmit_,a_Instr,_rv_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
     2521                                                uint8_t const idxSimdGstRegDst, uint8_t const idxVarSrc) \
     2522    { \
     2523        uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
     2524                                                                              kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); \
     2525        uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); \
     2526        PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2); \
     2527        pCodeBuf[off++] = Armv8A64MkVecInstrIns(IEMNATIVE_SIMD_REG_FIXED_TMP0, idxRegSrc, 0 /*idxElem*/); /* Transfer value from GPR to temporary vector register. */ \
     2528        pCodeBuf[off++] = Armv8A64MkVecInstrUShll(idxSimdRegDst, IEMNATIVE_SIMD_REG_FIXED_TMP0, 0, (a_ArmElemSz), (a_fArmUnsigned)); \
     2529        iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
     2530        iemNativeVarRegisterRelease(pReNative, idxVarSrc); \
     2531        IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
     2532        return off; \
     2533    } \
     2534    typedef int ignore_semicolon
     2535#else
     2536# error "Port me"
     2537#endif
     2538
     2539IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovzxbw, true,  kArmv8InstrShiftSz_U8,  0x30);
     2540IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovzxwd, true,  kArmv8InstrShiftSz_U16, 0x33);
     2541IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovzxdq, true,  kArmv8InstrShiftSz_U32, 0x35);
     2542
     2543IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovsxbw, false, kArmv8InstrShiftSz_U8,  0x20);
     2544IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovsxwd, false, kArmv8InstrShiftSz_U16, 0x23);
     2545IEMNATIVE_NATIVE_EMIT_PMOV_S_Z_U128(pmovsxdq, false, kArmv8InstrShiftSz_U32, 0x25);
     2546
    24442547#endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */
    24452548
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