- Timestamp:
- Dec 4, 2023 1:05:53 PM (18 months ago)
- svn:sync-xref-src-repo-rev:
- 160590
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r102443 r102447 2874 2874 'IEM_MC_FETCH_FSW': (McBlock.parseMcGeneric, False, False, ), 2875 2875 'IEM_MC_FETCH_GREG_U16': (McBlock.parseMcGeneric, False, True, ), 2876 'IEM_MC_FETCH_GREG_U16_SX_U32': (McBlock.parseMcGeneric, False, False,),2877 'IEM_MC_FETCH_GREG_U16_SX_U64': (McBlock.parseMcGeneric, False, False,),2878 'IEM_MC_FETCH_GREG_U16_ZX_U32': (McBlock.parseMcGeneric, False, False,),2879 'IEM_MC_FETCH_GREG_U16_ZX_U64': (McBlock.parseMcGeneric, False, False,),2876 'IEM_MC_FETCH_GREG_U16_SX_U32': (McBlock.parseMcGeneric, False, True, ), 2877 'IEM_MC_FETCH_GREG_U16_SX_U64': (McBlock.parseMcGeneric, False, True, ), 2878 'IEM_MC_FETCH_GREG_U16_ZX_U32': (McBlock.parseMcGeneric, False, True, ), 2879 'IEM_MC_FETCH_GREG_U16_ZX_U64': (McBlock.parseMcGeneric, False, True, ), 2880 2880 'IEM_MC_FETCH_GREG_U32': (McBlock.parseMcGeneric, False, True, ), 2881 'IEM_MC_FETCH_GREG_U32_SX_U64': (McBlock.parseMcGeneric, False, False,),2882 'IEM_MC_FETCH_GREG_U32_ZX_U64': (McBlock.parseMcGeneric, False, False,),2881 'IEM_MC_FETCH_GREG_U32_SX_U64': (McBlock.parseMcGeneric, False, True, ), 2882 'IEM_MC_FETCH_GREG_U32_ZX_U64': (McBlock.parseMcGeneric, False, True, ), 2883 2883 'IEM_MC_FETCH_GREG_U64': (McBlock.parseMcGeneric, False, False, ), 2884 2884 'IEM_MC_FETCH_GREG_U64_ZX_U64': (McBlock.parseMcGeneric, False, False, ), 2885 'IEM_MC_FETCH_GREG_U8': (McBlock.parseMcGeneric, False, False,),2886 'IEM_MC_FETCH_GREG_U8_SX_U16': (McBlock.parseMcGeneric, False, False,),2887 'IEM_MC_FETCH_GREG_U8_SX_U32': (McBlock.parseMcGeneric, False, False,),2888 'IEM_MC_FETCH_GREG_U8_SX_U64': (McBlock.parseMcGeneric, False, False,),2889 'IEM_MC_FETCH_GREG_U8_ZX_U16': (McBlock.parseMcGeneric, False, False,),2890 'IEM_MC_FETCH_GREG_U8_ZX_U32': (McBlock.parseMcGeneric, False, False,),2891 'IEM_MC_FETCH_GREG_U8_ZX_U64': (McBlock.parseMcGeneric, False, False,),2885 'IEM_MC_FETCH_GREG_U8': (McBlock.parseMcGeneric, False, True, ), 2886 'IEM_MC_FETCH_GREG_U8_SX_U16': (McBlock.parseMcGeneric, False, True, ), 2887 'IEM_MC_FETCH_GREG_U8_SX_U32': (McBlock.parseMcGeneric, False, True, ), 2888 'IEM_MC_FETCH_GREG_U8_SX_U64': (McBlock.parseMcGeneric, False, True, ), 2889 'IEM_MC_FETCH_GREG_U8_ZX_U16': (McBlock.parseMcGeneric, False, True, ), 2890 'IEM_MC_FETCH_GREG_U8_ZX_U32': (McBlock.parseMcGeneric, False, True, ), 2891 'IEM_MC_FETCH_GREG_U8_ZX_U64': (McBlock.parseMcGeneric, False, True, ), 2892 2892 'IEM_MC_FETCH_GREG_PAIR_U32': (McBlock.parseMcGeneric, False, False, ), 2893 2893 'IEM_MC_FETCH_GREG_PAIR_U64': (McBlock.parseMcGeneric, False, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py
r102444 r102447 93 93 'IEM_MC_STORE_GREG_U8_CONST_THREADED': (None, True, True, ), 94 94 'IEM_MC_FETCH_GREG_U8_THREADED': (None, False, True, ), 95 'IEM_MC_FETCH_GREG_U8_SX_U16_THREADED': (None, False, False,),96 'IEM_MC_FETCH_GREG_U8_SX_U32_THREADED': (None, False, False,),97 'IEM_MC_FETCH_GREG_U8_SX_U64_THREADED': (None, False, False,),98 'IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED': (None, False, False,),99 'IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED': (None, False, False,),100 'IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED': (None, False, False,),95 'IEM_MC_FETCH_GREG_U8_SX_U16_THREADED': (None, False, True, ), 96 'IEM_MC_FETCH_GREG_U8_SX_U32_THREADED': (None, False, True, ), 97 'IEM_MC_FETCH_GREG_U8_SX_U64_THREADED': (None, False, True, ), 98 'IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED': (None, False, True, ), 99 'IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED': (None, False, True, ), 100 'IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED': (None, False, True, ), 101 101 'IEM_MC_REF_GREG_U8_THREADED': (None, True, True, ), 102 102 -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r102444 r102447 7256 7256 7257 7257 #define IEM_MC_FETCH_GREG_U8_THREADED(a_u8Dst, a_iGRegEx) \ 7258 off = iemNativeEmitFetchGregU8(pReNative, off, a_u8Dst, a_iGRegEx) 7259 7260 /** Emits code for IEM_MC_FETCH_GREG_U8. */ 7258 off = iemNativeEmitFetchGregU8(pReNative, off, a_u8Dst, a_iGRegEx, sizeof(uint8_t) /*cbZeroExtended*/) 7259 7260 #define IEM_MC_FETCH_GREG_U8_ZX_U16_THREADED(a_u16Dst, a_iGRegEx) \ 7261 off = iemNativeEmitFetchGregU8(pReNative, off, a_u16Dst, a_iGRegEx, sizeof(uint16_t) /*cbZeroExtended*/) 7262 7263 #define IEM_MC_FETCH_GREG_U8_ZX_U32_THREADED(a_u32Dst, a_iGRegEx) \ 7264 off = iemNativeEmitFetchGregU8(pReNative, off, a_u32Dst, a_iGRegEx, sizeof(uint32_t) /*cbZeroExtended*/) 7265 7266 #define IEM_MC_FETCH_GREG_U8_ZX_U64_THREADED(a_u64Dst, a_iGRegEx) \ 7267 off = iemNativeEmitFetchGregU8(pReNative, off, a_u64Dst, a_iGRegEx, sizeof(uint64_t) /*cbZeroExtended*/) 7268 7269 7270 /** Emits code for IEM_MC_FETCH_GREG_U8_THREADED and 7271 * IEM_MC_FETCH_GREG_U8_ZX_U16/32/64_THREADED. */ 7261 7272 DECL_INLINE_THROW(uint32_t) 7262 iemNativeEmitFetchGregU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx )7273 iemNativeEmitFetchGregU8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx, int8_t cbZeroExtended) 7263 7274 { 7264 7275 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7265 Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint8_t));7276 Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF(cbZeroExtended); 7266 7277 Assert(iGRegEx < 20); 7267 7278 … … 7273 7284 uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off); 7274 7285 7286 /* The value is zero-extended to the full 64-bit host register width. */ 7275 7287 if (iGRegEx < 16) 7276 7288 off = iemNativeEmitLoadGprFromGpr8(pReNative, off, idxVarReg, idxGstFullReg); … … 7283 7295 7284 7296 7297 #define IEM_MC_FETCH_GREG_U8_SX_U16_THREADED(a_u16Dst, a_iGRegEx) \ 7298 off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u16Dst, a_iGRegEx, sizeof(uint16_t)) 7299 7300 #define IEM_MC_FETCH_GREG_U8_SX_U32_THREADED(a_u32Dst, a_iGRegEx) \ 7301 off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u32Dst, a_iGRegEx, sizeof(uint32_t)) 7302 7303 #define IEM_MC_FETCH_GREG_U8_SX_U64_THREADED(a_u64Dst, a_iGRegEx) \ 7304 off = iemNativeEmitFetchGregU8Sx(pReNative, off, a_u64Dst, a_iGRegEx, sizeof(uint64_t)) 7305 7306 /** Emits code for IEM_MC_FETCH_GREG_U8_SX_U16/32/64_THREADED. */ 7307 DECL_INLINE_THROW(uint32_t) 7308 iemNativeEmitFetchGregU8Sx(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGRegEx, uint8_t cbSignExtended) 7309 { 7310 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7311 Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbSignExtended); 7312 Assert(iGRegEx < 20); 7313 7314 /* Same discussion as in iemNativeEmitFetchGregU16 */ 7315 uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGRegEx & 15), 7316 kIemNativeGstRegUse_ReadOnly); 7317 7318 iemNativeVarSetKindToStack(pReNative, idxDstVar); 7319 uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off); 7320 7321 if (iGRegEx < 16) 7322 { 7323 switch (cbSignExtended) 7324 { 7325 case sizeof(uint16_t): 7326 off = iemNativeEmitLoadGpr16SignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg); 7327 break; 7328 case sizeof(uint32_t): 7329 off = iemNativeEmitLoadGpr32SignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg); 7330 break; 7331 case sizeof(uint64_t): 7332 off = iemNativeEmitLoadGprSignExtendedFromGpr8(pReNative, off, idxVarReg, idxGstFullReg); 7333 break; 7334 default: AssertFailed(); break; 7335 } 7336 } 7337 else 7338 { 7339 off = iemNativeEmitLoadGprFromGpr8Hi(pReNative, off, idxVarReg, idxGstFullReg); 7340 switch (cbSignExtended) 7341 { 7342 case sizeof(uint16_t): 7343 off = iemNativeEmitLoadGpr16SignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg); 7344 break; 7345 case sizeof(uint32_t): 7346 off = iemNativeEmitLoadGpr32SignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg); 7347 break; 7348 case sizeof(uint64_t): 7349 off = iemNativeEmitLoadGprSignExtendedFromGpr8(pReNative, off, idxVarReg, idxVarReg); 7350 break; 7351 default: AssertFailed(); break; 7352 } 7353 } 7354 7355 iemNativeRegFreeTmp(pReNative, idxGstFullReg); 7356 return off; 7357 } 7358 7359 7360 7285 7361 #define IEM_MC_FETCH_GREG_U16(a_u16Dst, a_iGReg) \ 7286 off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg) 7287 7288 /** Emits code for IEM_MC_FETCH_GREG_U16. */ 7362 off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint16_t)) 7363 7364 #define IEM_MC_FETCH_GREG_U16_ZX_U32(a_u16Dst, a_iGReg) \ 7365 off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint32_t)) 7366 7367 #define IEM_MC_FETCH_GREG_U16_ZX_U64(a_u16Dst, a_iGReg) \ 7368 off = iemNativeEmitFetchGregU16(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint64_t)) 7369 7370 /** Emits code for IEM_MC_FETCH_GREG_U16 and IEM_MC_FETCH_GREG_U16_ZX_U32/64. */ 7289 7371 DECL_INLINE_THROW(uint32_t) 7290 iemNativeEmitFetchGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg )7372 iemNativeEmitFetchGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbZeroExtended) 7291 7373 { 7292 7374 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7293 Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint16_t));7375 Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF(cbZeroExtended); 7294 7376 Assert(iGReg < 16); 7295 7377 … … 7313 7395 7314 7396 7315 #define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) \ 7316 off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg) 7317 7318 /** Emits code for IEM_MC_FETCH_GREG_U32. */ 7397 #define IEM_MC_FETCH_GREG_U16_SX_U32(a_u16Dst, a_iGReg) \ 7398 off = iemNativeEmitFetchGregU16Sx(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint32_t)) 7399 7400 #define IEM_MC_FETCH_GREG_U16_SX_U64(a_u16Dst, a_iGReg) \ 7401 off = iemNativeEmitFetchGregU16Sx(pReNative, off, a_u16Dst, a_iGReg, sizeof(uint64_t)) 7402 7403 /** Emits code for IEM_MC_FETCH_GREG_U16_SX_U32/64. */ 7319 7404 DECL_INLINE_THROW(uint32_t) 7320 iemNativeEmitFetchGregU 32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg)7405 iemNativeEmitFetchGregU16Sx(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbSignExtended) 7321 7406 { 7322 7407 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7323 Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint32_t));7408 Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbSignExtended); 7324 7409 Assert(iGReg < 16); 7325 7410 … … 7336 7421 iemNativeVarSetKindToStack(pReNative, idxDstVar); 7337 7422 uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off); 7423 if (cbSignExtended == sizeof(uint32_t)) 7424 off = iemNativeEmitLoadGpr32SignExtendedFromGpr16(pReNative, off, idxVarReg, idxGstFullReg); 7425 else 7426 { 7427 Assert(cbSignExtended == sizeof(uint64_t)); 7428 off = iemNativeEmitLoadGprSignExtendedFromGpr16(pReNative, off, idxVarReg, idxGstFullReg); 7429 } 7430 7431 iemNativeRegFreeTmp(pReNative, idxGstFullReg); 7432 return off; 7433 } 7434 7435 7436 #define IEM_MC_FETCH_GREG_U32(a_u32Dst, a_iGReg) \ 7437 off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg, sizeof(uint32_t)) 7438 7439 #define IEM_MC_FETCH_GREG_U32_ZX_U64(a_u32Dst, a_iGReg) \ 7440 off = iemNativeEmitFetchGregU32(pReNative, off, a_u32Dst, a_iGReg, sizeof(uint64_t)) 7441 7442 /** Emits code for IEM_MC_FETCH_GREG_U32. */ 7443 DECL_INLINE_THROW(uint32_t) 7444 iemNativeEmitFetchGregU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg, uint8_t cbZeroExtended) 7445 { 7446 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7447 Assert(pReNative->Core.aVars[idxDstVar].cbVar == cbZeroExtended); RT_NOREF_PV(cbZeroExtended); 7448 Assert(iGReg < 16); 7449 7450 /* 7451 * We can either just load the low 16-bit of the GPR into a host register 7452 * for the variable, or we can do so via a shadow copy host register. The 7453 * latter will avoid having to reload it if it's being stored later, but 7454 * will waste a host register if it isn't touched again. Since we don't 7455 * know what going to happen, we choose the latter for now. 7456 */ 7457 uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGReg), 7458 kIemNativeGstRegUse_ReadOnly); 7459 7460 iemNativeVarSetKindToStack(pReNative, idxDstVar); 7461 uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off); 7338 7462 off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxVarReg, idxGstFullReg); 7463 7464 iemNativeRegFreeTmp(pReNative, idxGstFullReg); 7465 return off; 7466 } 7467 7468 7469 #define IEM_MC_FETCH_GREG_U32_SX_U64(a_u32Dst, a_iGReg) \ 7470 off = iemNativeEmitFetchGregU32SxU64(pReNative, off, a_u32Dst, a_iGReg) 7471 7472 /** Emits code for IEM_MC_FETCH_GREG_U32. */ 7473 DECL_INLINE_THROW(uint32_t) 7474 iemNativeEmitFetchGregU32SxU64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDstVar, uint8_t iGReg) 7475 { 7476 Assert(idxDstVar < RT_ELEMENTS(pReNative->Core.aVars) && (pReNative->Core.bmVars & RT_BIT_32(idxDstVar))); 7477 Assert(pReNative->Core.aVars[idxDstVar].cbVar == sizeof(uint64_t)); 7478 Assert(iGReg < 16); 7479 7480 /* 7481 * We can either just load the low 16-bit of the GPR into a host register 7482 * for the variable, or we can do so via a shadow copy host register. The 7483 * latter will avoid having to reload it if it's being stored later, but 7484 * will waste a host register if it isn't touched again. Since we don't 7485 * know what going to happen, we choose the latter for now. 7486 */ 7487 uint8_t const idxGstFullReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(iGReg), 7488 kIemNativeGstRegUse_ReadOnly); 7489 7490 iemNativeVarSetKindToStack(pReNative, idxDstVar); 7491 uint8_t const idxVarReg = iemNativeVarAllocRegister(pReNative, idxDstVar, &off); 7492 off = iemNativeEmitLoadGprSignExtendedFromGpr32(pReNative, off, idxVarReg, idxGstFullReg); 7339 7493 7340 7494 iemNativeRegFreeTmp(pReNative, idxGstFullReg); … … 9422 9576 */ 9423 9577 //pReNative->pInstrBuf[off++] = 0xcc; 9578 RT_NOREF(fAccess); 9424 9579 9425 9580 #ifdef RT_ARCH_AMD64 -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r102444 r102447 770 770 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 771 771 pu32CodeBuf[off++] = Armv8A64MkInstrUbfx(iGprDst, iGprSrc, 8, 8, false /*f64Bit*/); 772 773 #else 774 # error "port me" 775 #endif 776 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 777 return off; 778 } 779 780 781 /** 782 * Sign-extends 32-bit value in @a iGprSrc into a 64-bit value in @a iGprDst. 783 */ 784 DECL_INLINE_THROW(uint32_t) 785 iemNativeEmitLoadGprSignExtendedFromGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 786 { 787 #ifdef RT_ARCH_AMD64 788 /* movsxd r64, r/m32 */ 789 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 790 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 791 pbCodeBuf[off++] = 0x63; 792 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 793 794 #elif defined(RT_ARCH_ARM64) 795 /* sxtw dst, src */ 796 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 797 pu32CodeBuf[off++] = Armv8A64MkInstrSxtw(iGprDst, iGprSrc); 798 799 #else 800 # error "port me" 801 #endif 802 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 803 return off; 804 } 805 806 807 /** 808 * Sign-extends 16-bit value in @a iGprSrc into a 64-bit value in @a iGprDst. 809 */ 810 DECL_INLINE_THROW(uint32_t) 811 iemNativeEmitLoadGprSignExtendedFromGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 812 { 813 #ifdef RT_ARCH_AMD64 814 /* movsx r64, r/m16 */ 815 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 816 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 817 pbCodeBuf[off++] = 0x0f; 818 pbCodeBuf[off++] = 0xbf; 819 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 820 821 #elif defined(RT_ARCH_ARM64) 822 /* sxth dst, src */ 823 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 824 pu32CodeBuf[off++] = Armv8A64MkInstrSxth(iGprDst, iGprSrc); 825 826 #else 827 # error "port me" 828 #endif 829 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 830 return off; 831 } 832 833 834 /** 835 * Sign-extends 16-bit value in @a iGprSrc into a 32-bit value in @a iGprDst. 836 */ 837 DECL_INLINE_THROW(uint32_t) 838 iemNativeEmitLoadGpr32SignExtendedFromGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 839 { 840 #ifdef RT_ARCH_AMD64 841 /* movsx r64, r/m16 */ 842 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 843 if (iGprDst >= 8 || iGprSrc >= 8) 844 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 845 pbCodeBuf[off++] = 0x0f; 846 pbCodeBuf[off++] = 0xbf; 847 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 848 849 #elif defined(RT_ARCH_ARM64) 850 /* sxth dst32, src */ 851 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 852 pu32CodeBuf[off++] = Armv8A64MkInstrSxth(iGprDst, iGprSrc, false /*f64Bit*/); 853 854 #else 855 # error "port me" 856 #endif 857 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 858 return off; 859 } 860 861 862 /** 863 * Sign-extends 8-bit value in @a iGprSrc into a 64-bit value in @a iGprDst. 864 */ 865 DECL_INLINE_THROW(uint32_t) 866 iemNativeEmitLoadGprSignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 867 { 868 #ifdef RT_ARCH_AMD64 869 /* movsx r64, r/m8 */ 870 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 871 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 872 pbCodeBuf[off++] = 0x0f; 873 pbCodeBuf[off++] = 0xbe; 874 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 875 876 #elif defined(RT_ARCH_ARM64) 877 /* sxtb dst, src */ 878 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 879 pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc); 880 881 #else 882 # error "port me" 883 #endif 884 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 885 return off; 886 } 887 888 889 /** 890 * Sign-extends 8-bit value in @a iGprSrc into a 32-bit value in @a iGprDst. 891 * @note Bits 64 thru 32 are cleared. 892 */ 893 DECL_INLINE_THROW(uint32_t) 894 iemNativeEmitLoadGpr32SignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 895 { 896 #ifdef RT_ARCH_AMD64 897 /* movsx r32, r/m8 */ 898 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 899 if (iGprDst >= 8 || iGprSrc >= 8) 900 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 901 pbCodeBuf[off++] = 0x0f; 902 pbCodeBuf[off++] = 0xbe; 903 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 904 905 #elif defined(RT_ARCH_ARM64) 906 /* sxtb dst32, src32 */ 907 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 908 pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc, false /*f64Bit*/); 909 910 #else 911 # error "port me" 912 #endif 913 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 914 return off; 915 } 916 917 918 /** 919 * Sign-extends 8-bit value in @a iGprSrc into a 16-bit value in @a iGprDst. 920 * @note Bits 64 thru 16 are cleared. 921 */ 922 DECL_INLINE_THROW(uint32_t) 923 iemNativeEmitLoadGpr16SignExtendedFromGpr8(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint8_t iGprSrc) 924 { 925 #ifdef RT_ARCH_AMD64 926 /* movsx r16, r/m8 */ 927 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 9); 928 pbCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 929 if (iGprDst >= 8 || iGprSrc >= 8) 930 pbCodeBuf[off++] = (iGprDst < 8 ? 0 : X86_OP_REX_R) | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 931 pbCodeBuf[off++] = 0x0f; 932 pbCodeBuf[off++] = 0xbe; 933 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprSrc & 7); 934 935 /* movzx r32, r/m16 */ 936 if (iGprDst >= 8) 937 pbCodeBuf[off++] = X86_OP_REX_R | X86_OP_REX_B; 938 pbCodeBuf[off++] = 0x0f; 939 pbCodeBuf[off++] = 0xb7; 940 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprDst & 7, iGprDst & 7); 941 942 #elif defined(RT_ARCH_ARM64) 943 /* sxtb dst32, src32; and dst32, dst32, #0xffff */ 944 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2); 945 pu32CodeBuf[off++] = Armv8A64MkInstrSxtb(iGprDst, iGprSrc, false /*f64Bit*/); 946 Assert(Armv8A64ConvertImmRImmS2Mask32(15, 0) == 0xffff); 947 pu32CodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, 15, 0, false /*f64Bit*/); 772 948 773 949 #else
Note:
See TracChangeset
for help on using the changeset viewer.