Changeset 103991 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Mar 21, 2024 2:30:04 PM (11 months ago)
- svn:sync-xref-src-repo-rev:
- 162376
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
r103990 r103991 7199 7199 iemNativeEmitSimdCopyXregU128(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iXRegDst, uint8_t iXRegSrc) 7200 7200 { 7201 /* 7202 * Allocate destination and source register. 7203 * 7204 * @note The order is important here when iXRegSrc == iXRegDst, because if iXRegDst gets allocated first for the full write 7205 * it won't load the actual value from CPUMCTX. When allocating iXRegSrc afterwards it will get duplicated from the already 7206 * allocated host register for iXRegDst containing garbage. This will be catched by the guest register value checking. 7207 */ 7208 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXRegSrc), 7209 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); 7210 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXRegDst), 7211 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); 7212 7213 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7214 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iXRegDst); 7215 /* We don't need to write everything back here as the destination is marked as dirty and will be flushed automatically. */ 7216 7217 /* Free but don't flush the source and destination register. */ 7218 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7219 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7201 /* This is a nop if the source and destination register are the same. */ 7202 if (iXRegDst != iXRegSrc) 7203 { 7204 /* Allocate destination and source register. */ 7205 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXRegDst), 7206 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForFullWrite); 7207 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iXRegSrc), 7208 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); 7209 7210 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7211 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iXRegDst); 7212 /* We don't need to write everything back here as the destination is marked as dirty and will be flushed automatically. */ 7213 7214 /* Free but don't flush the source and destination register. */ 7215 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7216 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7217 } 7220 7218 7221 7219 return off; … … 7521 7519 { 7522 7520 /* 7523 * Allocate destination and source register. 7524 * 7525 * @note The order is important here when iYRegSrc == iYRegDst, because if iYRegDst gets allocated first for the full write 7526 * it won't load the actual value from CPUMCTX. When allocating iYRegSrc afterwards it will get duplicated from the already 7527 * allocated host register for iYRegDst containing garbage. This will be catched by the guest register value checking. 7521 * The iYRegSrc == iYRegDst case needs to be treated differently here, because if iYRegDst gets allocated first for the full write 7522 * it won't load the actual value from CPUMCTX. When allocating iYRegSrc afterwards it will get duplicated from the already 7523 * allocated host register for iYRegDst containing garbage. This will be catched by the guest register value checking in debug builds. 7528 7524 */ 7529 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegSrc), 7530 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); 7531 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegDst), 7532 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ForFullWrite); 7533 7534 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7535 off = iemNativeEmitSimdZeroVecRegHighU128(pReNative, off, idxSimdRegDst); 7536 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iYRegDst); 7537 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(pReNative, iYRegDst); 7538 7539 /* Free but don't flush the source and destination register. */ 7540 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7541 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7525 if (iYRegDst != iYRegSrc) 7526 { 7527 /* Allocate destination and source register. */ 7528 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegDst), 7529 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ForFullWrite); 7530 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegSrc), 7531 kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ReadOnly); 7532 7533 off = iemNativeEmitSimdLoadVecRegFromVecRegU128(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7534 off = iemNativeEmitSimdZeroVecRegHighU128(pReNative, off, idxSimdRegDst); 7535 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iYRegDst); 7536 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(pReNative, iYRegDst); 7537 7538 /* Free but don't flush the source and destination register. */ 7539 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7540 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7541 } 7542 else 7543 { 7544 /* This effectively only clears the upper 128-bits of the register. */ 7545 uint8_t const idxSimdReg = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegDst), 7546 kIemNativeGstSimdRegLdStSz_High128, kIemNativeGstRegUse_ForFullWrite); 7547 7548 off = iemNativeEmitSimdZeroVecRegHighU128(pReNative, off, idxSimdReg); 7549 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(pReNative, iYRegDst); 7550 7551 /* Free but don't flush the destination register. */ 7552 iemNativeSimdRegFreeTmp(pReNative, idxSimdReg); 7553 } 7542 7554 7543 7555 return off; … … 7553 7565 { 7554 7566 /* 7555 * Allocate destination and source register. 7556 * 7557 * @note The order is important here when iYRegSrc == iYRegDst, because if iYRegDst gets allocated first for the full write 7558 * it won't load the actual value from CPUMCTX. When allocating iYRegSrc afterwards it will get duplicated from the already 7559 * allocated host register for iYRegDst containing garbage. This will be catched by the guest register value checking. 7567 * The iYRegSrc == iYRegDst case needs to be treated differently here, because if iYRegDst gets allocated first for the full write 7568 * it won't load the actual value from CPUMCTX. When allocating iYRegSrc afterwards it will get duplicated from the already 7569 * allocated host register for iYRegDst containing garbage. This will be catched by the guest register value checking in debug builds. 7570 * iYRegSrc == iYRegDst would effectively only clear any upper 256-bits for a zmm register we don't support yet, so this is just a nop. 7560 7571 */ 7561 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegSrc), 7562 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ReadOnly); 7563 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegDst), 7564 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ForFullWrite); 7565 7566 off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7567 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iYRegDst); 7568 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(pReNative, iYRegDst); 7569 7570 /* Free but don't flush the source and destination register. */ 7571 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7572 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7572 if (iYRegDst != iYRegSrc) 7573 { 7574 /* Allocate destination and source register. */ 7575 uint8_t const idxSimdRegSrc = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegSrc), 7576 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ReadOnly); 7577 uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(iYRegDst), 7578 kIemNativeGstSimdRegLdStSz_256, kIemNativeGstRegUse_ForFullWrite); 7579 7580 off = iemNativeEmitSimdLoadVecRegFromVecRegU256(pReNative, off, idxSimdRegDst, idxSimdRegSrc); 7581 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(pReNative, iYRegDst); 7582 IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(pReNative, iYRegDst); 7583 7584 /* Free but don't flush the source and destination register. */ 7585 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); 7586 iemNativeSimdRegFreeTmp(pReNative, idxSimdRegSrc); 7587 } 7573 7588 7574 7589 return off;
Note:
See TracChangeset
for help on using the changeset viewer.