Changeset 104984 in vbox for trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
- Timestamp:
- Jun 20, 2024 2:07:04 PM (9 months ago)
- svn:sync-xref-src-repo-rev:
- 163594
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h ¶
r104798 r104984 632 632 } 633 633 634 635 634 /** 636 635 * Emits a 32-bit GPR load of a VCpu value. … … 638 637 */ 639 638 DECL_INLINE_THROW(uint32_t) 639 iemNativeEmitLoadGprFromVCpuU32Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 640 { 641 #ifdef RT_ARCH_AMD64 642 /* mov reg32, mem32 */ 643 if (iGpr >= 8) 644 pCodeBuf[off++] = X86_OP_REX_R; 645 pCodeBuf[off++] = 0x8b; 646 off = iemNativeEmitGprByVCpuDisp(pCodeBuf, off, iGpr, offVCpu); 647 648 #elif defined(RT_ARCH_ARM64) 649 off = iemNativeEmitGprByVCpuLdStEx(pCodeBuf, off, iGpr, offVCpu, kArmv8A64InstrLdStType_Ld_Word, sizeof(uint32_t)); 650 651 #else 652 # error "port me" 653 #endif 654 return off; 655 } 656 657 658 /** 659 * Emits a 32-bit GPR load of a VCpu value. 660 * @note Bits 32 thru 63 in the GPR will be zero after the operation. 661 */ 662 DECL_INLINE_THROW(uint32_t) 640 663 iemNativeEmitLoadGprFromVCpuU32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr, uint32_t offVCpu) 641 664 { 642 665 #ifdef RT_ARCH_AMD64 643 /* mov reg32, mem32 */ 644 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 645 if (iGpr >= 8) 646 pbCodeBuf[off++] = X86_OP_REX_R; 647 pbCodeBuf[off++] = 0x8b; 648 off = iemNativeEmitGprByVCpuDisp(pbCodeBuf, off, iGpr, offVCpu); 666 off = iemNativeEmitLoadGprFromVCpuU32Ex(iemNativeInstrBufEnsure(pReNative, off, 7), off, iGpr, offVCpu); 649 667 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 650 668 … … 6952 6970 */ 6953 6971 DECL_INLINE_THROW(uint32_t) 6954 iemNativeEmitTestBitInGprAndJmpTo LabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc,6955 uint8_t iBitNo, uint32_t idxLabel, bool fJmpIfSet)6972 iemNativeEmitTestBitInGprAndJmpToFixedIfCcEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprSrc, uint8_t iBitNo, 6973 uint32_t offTarget, uint32_t *poffFixup, bool fJmpIfSet) 6956 6974 { 6957 6975 Assert(iBitNo < 64); 6958 6976 #ifdef RT_ARCH_AMD64 6959 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);6960 6977 if (iBitNo < 8) 6961 6978 { 6962 6979 /* test Eb, imm8 */ 6963 6980 if (iGprSrc >= 4) 6964 pbCodeBuf[off++] = iGprSrc >= 8 ? X86_OP_REX_B : X86_OP_REX; 6965 pbCodeBuf[off++] = 0xf6; 6966 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprSrc & 7); 6967 pbCodeBuf[off++] = (uint8_t)1 << iBitNo; 6968 off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_ne : kIemNativeInstrCond_e); 6981 pCodeBuf[off++] = iGprSrc >= 8 ? X86_OP_REX_B : X86_OP_REX; 6982 pCodeBuf[off++] = 0xf6; 6983 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprSrc & 7); 6984 pCodeBuf[off++] = (uint8_t)1 << iBitNo; 6985 if (poffFixup) 6986 *poffFixup = off; 6987 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, offTarget, fJmpIfSet ? kIemNativeInstrCond_ne : kIemNativeInstrCond_e); 6969 6988 } 6970 6989 else … … 6972 6991 /* bt Ev, imm8 */ 6973 6992 if (iBitNo >= 32) 6974 p bCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_B);6993 pCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 6975 6994 else if (iGprSrc >= 8) 6976 pbCodeBuf[off++] = X86_OP_REX_B; 6977 pbCodeBuf[off++] = 0x0f; 6978 pbCodeBuf[off++] = 0xba; 6979 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7); 6980 pbCodeBuf[off++] = iBitNo; 6981 off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_c : kIemNativeInstrCond_nc); 6995 pCodeBuf[off++] = X86_OP_REX_B; 6996 pCodeBuf[off++] = 0x0f; 6997 pCodeBuf[off++] = 0xba; 6998 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7); 6999 pCodeBuf[off++] = iBitNo; 7000 if (poffFixup) 7001 *poffFixup = off; 7002 off = iemNativeEmitJccToFixedEx(pCodeBuf, off, offTarget, fJmpIfSet ? kIemNativeInstrCond_c : kIemNativeInstrCond_nc); 7003 } 7004 7005 #elif defined(RT_ARCH_ARM64) 7006 /* Just use the TBNZ instruction here. */ 7007 if (poffFixup) 7008 *poffFixup = off; 7009 pCodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, off - offTarget, iGprSrc, iBitNo); 7010 7011 #else 7012 # error "Port me!" 7013 #endif 7014 return off; 7015 } 7016 7017 7018 /** 7019 * Emits a jump to @a idxTarget on the condition that bit @a iBitNo _is_ _set_ 7020 * in @a iGprSrc. 7021 */ 7022 DECL_INLINE_THROW(uint32_t) 7023 iemNativeEmitTestBitInGprAndJmpToFixedIfSetEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprSrc, uint8_t iBitNo, 7024 uint32_t offTarget, uint32_t *poffFixup) 7025 { 7026 return iemNativeEmitTestBitInGprAndJmpToFixedIfCcEx(pCodeBuf, off, iGprSrc, iBitNo, offTarget, poffFixup, true /*fJmpIfSet*/); 7027 } 7028 7029 7030 /** 7031 * Emits a jump to @a idxTarget on the condition that bit @a iBitNo _is_ _not_ 7032 * _set_ in @a iGprSrc. 7033 */ 7034 DECL_INLINE_THROW(uint32_t) 7035 iemNativeEmitTestBitInGprAndJmpToLabelIfNotSetEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprSrc, uint8_t iBitNo, 7036 uint32_t offTarget, uint32_t *poffFixup) 7037 { 7038 return iemNativeEmitTestBitInGprAndJmpToFixedIfCcEx(pCodeBuf, off, iGprSrc, iBitNo, offTarget, poffFixup, false /*fJmpIfSet*/); 7039 } 7040 7041 7042 7043 /** 7044 * Internal helper, don't call directly. 7045 */ 7046 DECL_INLINE_THROW(uint32_t) 7047 iemNativeEmitTestBitInGprAndJmpToLabelIfCcEx(PIEMRECOMPILERSTATE pReNative, PIEMNATIVEINSTR pCodeBuf, uint32_t off, 7048 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel, bool fJmpIfSet) 7049 { 7050 Assert(iBitNo < 64); 7051 #ifdef RT_ARCH_AMD64 7052 if (iBitNo < 8) 7053 { 7054 /* test Eb, imm8 */ 7055 if (iGprSrc >= 4) 7056 pCodeBuf[off++] = iGprSrc >= 8 ? X86_OP_REX_B : X86_OP_REX; 7057 pCodeBuf[off++] = 0xf6; 7058 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprSrc & 7); 7059 pCodeBuf[off++] = (uint8_t)1 << iBitNo; 7060 off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabel, 7061 fJmpIfSet ? kIemNativeInstrCond_ne : kIemNativeInstrCond_e); 7062 } 7063 else 7064 { 7065 /* bt Ev, imm8 */ 7066 if (iBitNo >= 32) 7067 pCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_B); 7068 else if (iGprSrc >= 8) 7069 pCodeBuf[off++] = X86_OP_REX_B; 7070 pCodeBuf[off++] = 0x0f; 7071 pCodeBuf[off++] = 0xba; 7072 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7); 7073 pCodeBuf[off++] = iBitNo; 7074 off = iemNativeEmitJccToLabelEx(pReNative, pCodeBuf, off, idxLabel, 7075 fJmpIfSet ? kIemNativeInstrCond_c : kIemNativeInstrCond_nc); 6982 7076 } 6983 7077 6984 7078 #elif defined(RT_ARCH_ARM64) 6985 7079 /* Use the TBNZ instruction here. */ 6986 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2);6987 7080 if (pReNative->paLabels[idxLabel].enmType > kIemNativeLabelType_LastWholeTbBranch) 6988 7081 { … … 6993 7086 { 6994 7087 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm14At5); 6995 p u32CodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, 0, iGprSrc, iBitNo);7088 pCodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, 0, iGprSrc, iBitNo); 6996 7089 } 6997 7090 //else … … 6999 7092 // RT_BREAKPOINT(); 7000 7093 // Assert(off - offLabel <= 0x1fffU); 7001 // p u32CodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, offLabel - off, iGprSrc, iBitNo);7094 // pCodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, offLabel - off, iGprSrc, iBitNo); 7002 7095 // 7003 7096 //} … … 7006 7099 { 7007 7100 Assert(Armv8A64ConvertImmRImmS2Mask64(0x40, (64U - iBitNo) & 63U) == RT_BIT_64(iBitNo)); 7008 p u32CodeBuf[off++] = Armv8A64MkInstrTstImm(iGprSrc, 0x40, (64U - iBitNo) & 63U);7101 pCodeBuf[off++] = Armv8A64MkInstrTstImm(iGprSrc, 0x40, (64U - iBitNo) & 63U); 7009 7102 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5); 7010 p u32CodeBuf[off++] = Armv8A64MkInstrBCond(fJmpIfSet ? kArmv8InstrCond_Ne : kArmv8InstrCond_Eq, 0);7103 pCodeBuf[off++] = Armv8A64MkInstrBCond(fJmpIfSet ? kArmv8InstrCond_Ne : kArmv8InstrCond_Eq, 0); 7011 7104 } 7012 7105 … … 7014 7107 # error "Port me!" 7015 7108 #endif 7016 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);7017 7109 return off; 7018 7110 } … … 7022 7114 * Emits a jump to @a idxLabel on the condition that bit @a iBitNo _is_ _set_ in 7023 7115 * @a iGprSrc. 7024 * 7025 * @note On ARM64 the range is only +/-8191 instructions. 7116 */ 7117 DECL_INLINE_THROW(uint32_t) 7118 iemNativeEmitTestBitInGprAndJmpToLabelIfSetEx(PIEMRECOMPILERSTATE pReNative, PIEMNATIVEINSTR pCodeBuf, uint32_t off, 7119 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 7120 { 7121 return iemNativeEmitTestBitInGprAndJmpToLabelIfCcEx(pReNative, pCodeBuf, off, iGprSrc, iBitNo, idxLabel, true /*fJmpIfSet*/); 7122 } 7123 7124 7125 /** 7126 * Emits a jump to @a idxLabel on the condition that bit @a iBitNo _is_ _not_ 7127 * _set_ in @a iGprSrc. 7128 */ 7129 DECL_INLINE_THROW(uint32_t) 7130 iemNativeEmitTestBitInGprAndJmpToLabelIfNotSetEx(PIEMRECOMPILERSTATE pReNative, PIEMNATIVEINSTR pCodeBuf, uint32_t off, 7131 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel) 7132 { 7133 return iemNativeEmitTestBitInGprAndJmpToLabelIfCcEx(pReNative, pCodeBuf, off, iGprSrc, iBitNo, idxLabel, false /*fJmpIfSet*/); 7134 } 7135 7136 7137 /** 7138 * Internal helper, don't call directly. 7139 */ 7140 DECL_INLINE_THROW(uint32_t) 7141 iemNativeEmitTestBitInGprAndJmpToLabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, 7142 uint8_t iBitNo, uint32_t idxLabel, bool fJmpIfSet) 7143 { 7144 #ifdef RT_ARCH_AMD64 7145 off = iemNativeEmitTestBitInGprAndJmpToLabelIfCcEx(pReNative, iemNativeInstrBufEnsure(pReNative, off, 5+6), off, 7146 iGprSrc, iBitNo, idxLabel, fJmpIfSet); 7147 #elif defined(RT_ARCH_ARM64) 7148 off = iemNativeEmitTestBitInGprAndJmpToLabelIfCcEx(pReNative, iemNativeInstrBufEnsure(pReNative, off, 2), off, 7149 iGprSrc, iBitNo, idxLabel, fJmpIfSet); 7150 #else 7151 # error "Port me!" 7152 #endif 7153 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 7154 return off; 7155 } 7156 7157 7158 /** 7159 * Emits a jump to @a idxLabel on the condition that bit @a iBitNo _is_ _set_ in 7160 * @a iGprSrc. 7026 7161 */ 7027 7162 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, … … 7035 7170 * Emits a jump to @a idxLabel on the condition that bit @a iBitNo _is_ _not_ 7036 7171 * _set_ in @a iGprSrc. 7037 *7038 * @note On ARM64 the range is only +/-8191 instructions.7039 7172 */ 7040 7173 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off,
Note:
See TracChangeset
for help on using the changeset viewer.