Changeset 103815 in vbox for trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
- Timestamp:
- Mar 13, 2024 8:13:38 AM (11 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r103814 r103815 7396 7396 } 7397 7397 7398 7399 /** 7400 * Emits a vecdst = gprsrc broadcast, 64-bit. 7401 */ 7402 DECL_FORCE_INLINE(uint32_t) 7403 iemNativeEmitSimdBroadcastGprToVecRegU64Ex(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 */ 7464 DECL_INLINE_THROW(uint32_t) 7465 iemNativeEmitSimdBroadcastGprToVecRegU64(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 7398 7478 #endif /* IEMNATIVE_WITH_SIMD_REG_ALLOCATOR */ 7399 7479
Note:
See TracChangeset
for help on using the changeset viewer.