Changeset 102510 in vbox
- Timestamp:
- Dec 6, 2023 9:39:10 PM (12 months ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/armv8.h
r102449 r102510 2656 2656 2657 2657 2658 /** A64: Encodes an MOV instruction. 2659 * This is an alias for "orr dst, xzr, src". */ 2660 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrMov(uint32_t iRegResult, uint32_t idxRegSrc, bool f64Bit = true) 2661 { 2662 return Armv8A64MkInstrOrr(iRegResult, ARMV8_A64_REG_XZR, idxRegSrc, f64Bit); 2663 } 2664 2665 2658 2666 /** A64: Encodes an ORN instruction. 2659 2667 * @see Armv8A64MkInstrLogicalShiftedReg for parameter details. */ -
trunk/src/VBox/VMM/VMMAll/IEMAllInstCommon.cpp.h
r102011 r102510 1033 1033 IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm, 0); 1034 1034 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 1035 IEM_MC_NO_NATIVE_RECOMPILE(); /** @todo sort out the IEM_IS_GUEST_CPU_AMD stuff. */ 1035 1036 if (IEM_IS_GUEST_CPU_AMD(pVCpu)) /** @todo testcase: rev 3.15 of the amd manuals claims it only loads a 32-bit greg. */ 1036 1037 IEM_MC_FETCH_MEM_U32_SX_U64(offSeg, pVCpu->iem.s.iEffSeg, GCPtrEff); -
trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py
r102447 r102510 62 62 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_16': (None, False, True, ), 63 63 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_32': (None, False, True, ), 64 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32': (None, False, False,),65 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS': (None, False, False,),66 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64': (None, False, False,),64 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32': (None, False, True, ), 65 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS': (None, False, True, ), 66 'IEM_MC_CALC_RM_EFF_ADDR_THREADED_64': (None, False, True, ), 67 67 68 68 'IEM_MC_CALL_CIMPL_1_THREADED': (None, True, True, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r102471 r102510 6 6 * - Level 1 (Log) : ... 7 7 * - Flow (LogFlow) : ... 8 * - Level 2 (Log2) : ...8 * - Level 2 (Log2) : Details calls as they're recompiled. 9 9 * - Level 3 (Log3) : Disassemble native code after recompiling. 10 10 * - Level 4 (Log4) : ... … … 3438 3438 && enmIntendedUse != kIemNativeGstRegUse_ForFullWrite, 3439 3439 ("This shouldn't happen: idxReg=%d enmGstReg=%d enmIntendedUse=%s\n", 3440 idxReg, s_pszIntendedUse[enmIntendedUse]));3440 idxReg, enmGstReg, s_pszIntendedUse[enmIntendedUse])); 3441 3441 3442 3442 /* … … 8729 8729 8730 8730 #define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \ 8731 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff) 8731 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \ 8732 a_u32Disp, a_cbImm, a_GCPtrEff, true /*f64Bit*/) 8732 8733 8733 8734 #define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_FSGS(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \ 8734 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff, 64) 8735 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \ 8736 a_u32Disp, a_cbImm, a_GCPtrEff, true /*f64Bit*/) 8735 8737 8736 8738 #define IEM_MC_CALC_RM_EFF_ADDR_THREADED_64_ADDR32(a_GCPtrEff, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm) \ 8737 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, a_u32Disp, a_cbImm, a_GCPtrEff, 32) 8739 off = iemNativeEmitCalcRmEffAddrThreadedAddr64(pReNative, off, a_bRmEx, a_uSibAndRspOffset, \ 8740 a_u32Disp, a_cbImm, a_GCPtrEff, false /*f64Bit*/) 8741 8742 /** 8743 * Emit code for IEM_MC_CALC_RM_EFF_ADDR_THREADED_64*. 8744 * 8745 * @returns New off. 8746 * @param pReNative . 8747 * @param off . 8748 * @param bRmEx The ModRM byte but with bit 3 set to REX.B and 8749 * bit 4 to REX.X. The two bits are part of the 8750 * REG sub-field, which isn't needed in this 8751 * function. 8752 * @param uSibAndRspOffset Two parts: 8753 * - The first 8 bits make up the SIB byte. 8754 * - The next 8 bits are the fixed RSP/ESP offset 8755 * in case of a pop [xSP]. 8756 * @param u32Disp The displacement byte/word/dword, if any. 8757 * @param cbInstr The size of the fully decoded instruction. Used 8758 * for RIP relative addressing. 8759 * @param idxVarRet . 8760 * 8761 * @see iemOpHlpCalcRmEffAddrThreadedAddr64 8762 */ 8763 DECL_INLINE_THROW(uint32_t) 8764 iemNativeEmitCalcRmEffAddrThreadedAddr64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t bRmEx, uint32_t uSibAndRspOffset, 8765 uint32_t u32Disp, uint8_t cbInstr, uint8_t idxVarRet, bool f64Bit) 8766 { 8767 IEMNATIVE_ASSERT_VAR_IDX(pReNative, idxVarRet); 8768 8769 /* 8770 * Special case the rip + disp32 form first. 8771 */ 8772 if ((bRmEx & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5) 8773 { 8774 uint8_t const idxRegRet = iemNativeVarAllocRegister(pReNative, idxVarRet, &off); 8775 uint8_t const idxRegPc = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc, 8776 kIemNativeGstRegUse_ReadOnly); 8777 #ifdef RT_ARCH_AMD64 8778 if (f64Bit) 8779 { 8780 int64_t const offFinalDisp = (int64_t)(int32_t)u32Disp + cbInstr; 8781 if ((int32_t)offFinalDisp == offFinalDisp) 8782 off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)offFinalDisp); 8783 else 8784 { 8785 off = iemNativeEmitLoadGprFromGprWithAddend(pReNative, off, idxRegRet, idxRegPc, (int32_t)u32Disp); 8786 off = iemNativeEmitAddGprImm8(pReNative, off, idxRegRet, cbInstr); 8787 } 8788 } 8789 else 8790 off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, (int32_t)u32Disp + cbInstr); 8791 8792 #elif defined(RT_ARCH_ARM64) 8793 if (f64Bit) 8794 off = iemNativeEmitLoadGprFromGprWithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, 8795 (int64_t)(int32_t)u32Disp + cbInstr); 8796 else 8797 off = iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(pReNative, off, idxRegRet, idxRegPc, 8798 (int32_t)u32Disp + cbInstr); 8799 8800 #else 8801 # error "Port me!" 8802 #endif 8803 iemNativeRegFreeTmp(pReNative, idxRegPc); 8804 return off; 8805 } 8806 8807 /* Calculate the fixed displacement (more down in SIB.B=4 and SIB.B=5 on this). */ 8808 int64_t i64EffAddr = 0; 8809 switch ((bRmEx >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK) 8810 { 8811 case 0: break; 8812 case 1: i64EffAddr = (int8_t)u32Disp; break; 8813 case 2: i64EffAddr = (int32_t)u32Disp; break; 8814 default: AssertFailed(); 8815 } 8816 8817 /* Get the register (or SIB) value. */ 8818 uint8_t idxGstRegBase = UINT8_MAX; 8819 uint8_t idxGstRegIndex = UINT8_MAX; 8820 uint8_t cShiftIndex = 0; 8821 if ((bRmEx & X86_MODRM_RM_MASK) != 4) 8822 idxGstRegBase = bRmEx & (X86_MODRM_RM_MASK | 0x8); /* bRmEx[bit 3] = REX.B */ 8823 else /* SIB: */ 8824 { 8825 /* index /w scaling . */ 8826 cShiftIndex = (uSibAndRspOffset >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK; 8827 idxGstRegIndex = ((uSibAndRspOffset >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) 8828 | ((bRmEx & 0x10) >> 1); /* bRmEx[bit 4] = REX.X */ 8829 if (idxGstRegIndex == 4) 8830 { 8831 /* no index */ 8832 cShiftIndex = 0; 8833 idxGstRegIndex = UINT8_MAX; 8834 } 8835 8836 /* base */ 8837 idxGstRegBase = (uSibAndRspOffset & X86_SIB_BASE_MASK) | (bRmEx & 0x8); /* bRmEx[bit 3] = REX.B */ 8838 if (idxGstRegBase == 4) 8839 { 8840 /* pop [rsp] hack */ 8841 i64EffAddr += uSibAndRspOffset >> 8; /* (this is why i64EffAddr must be 64-bit) */ 8842 } 8843 else if ( (idxGstRegBase & X86_SIB_BASE_MASK) == 5 8844 && (bRmEx & X86_MODRM_MOD_MASK) == 0) 8845 { 8846 /* mod=0 and base=5 -> disp32, no base reg. */ 8847 Assert(i64EffAddr == 0); 8848 i64EffAddr = (int32_t)u32Disp; 8849 idxGstRegBase = UINT8_MAX; 8850 } 8851 } 8852 8853 /* 8854 * If no registers are involved (SIB.B=5, SIB.X=4) repeat what we did at 8855 * the start of the function. 8856 */ 8857 if (idxGstRegBase == UINT8_MAX && idxGstRegIndex == UINT8_MAX) 8858 { 8859 if (f64Bit) 8860 iemNativeVarSetKindToConst(pReNative, idxVarRet, (uint64_t)i64EffAddr); 8861 else 8862 iemNativeVarSetKindToConst(pReNative, idxVarRet, (uint64_t)(int32_t)i64EffAddr); 8863 return off; 8864 } 8865 8866 /* 8867 * Now emit code that calculates: 8868 * idxRegRet = (uint64_t)(i64EffAddr [+ idxGstRegBase] [+ (idxGstRegIndex << cShiftIndex)]) 8869 * or if !f64Bit: 8870 * idxRegRet = (uint32_t)(i64EffAddr [+ idxGstRegBase] [+ (idxGstRegIndex << cShiftIndex)]) 8871 */ 8872 uint8_t const idxRegRet = iemNativeVarAllocRegister(pReNative, idxVarRet, &off); 8873 uint8_t idxRegBase = idxGstRegBase == UINT8_MAX ? UINT8_MAX 8874 : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(idxGstRegBase), 8875 kIemNativeGstRegUse_ReadOnly); 8876 uint8_t idxRegIndex = idxGstRegIndex == UINT8_MAX ? UINT8_MAX 8877 : iemNativeRegAllocTmpForGuestReg(pReNative, &off, IEMNATIVEGSTREG_GPR(idxGstRegIndex), 8878 kIemNativeGstRegUse_ReadOnly); 8879 8880 /* If base is not given and there is no shifting, swap the registers to avoid code duplication. */ 8881 if (idxRegBase == UINT8_MAX && cShiftIndex == 0) 8882 { 8883 idxRegBase = idxRegIndex; 8884 idxRegIndex = UINT8_MAX; 8885 } 8886 8887 #ifdef RT_ARCH_AMD64 8888 uint8_t bFinalAdj; 8889 if (!f64Bit || (int32_t)i64EffAddr == i64EffAddr) 8890 bFinalAdj = 0; /* likely */ 8891 else 8892 { 8893 /* pop [rsp] with a problematic disp32 value. Split out the 8894 RSP offset and add it separately afterwards (bFinalAdj). */ 8895 /** @todo testcase: pop [rsp] with problematic disp32 (mod4). */ 8896 Assert(idxGstRegBase == X86_GREG_xSP); 8897 Assert(((bRmEx >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK) == X86_MOD_MEM4); 8898 bFinalAdj = (uint8_t)(uSibAndRspOffset >> 8); 8899 Assert(bFinalAdj != 0); 8900 i64EffAddr -= bFinalAdj; 8901 Assert((int32_t)i64EffAddr == i64EffAddr); 8902 } 8903 uint32_t const u32EffAddr = (uint32_t)i64EffAddr; 8904 //pReNative->pInstrBuf[off++] = 0xcc; 8905 8906 if (idxRegIndex == UINT8_MAX) 8907 { 8908 if (u32EffAddr == 0) 8909 { 8910 /* mov ret, base */ 8911 if (f64Bit) 8912 off = iemNativeEmitLoadGprFromGpr(pReNative, off, idxRegRet, idxRegBase); 8913 else 8914 off = iemNativeEmitLoadGprFromGpr32(pReNative, off, idxRegRet, idxRegBase); 8915 } 8916 else 8917 { 8918 /* lea ret, [base + disp32] */ 8919 Assert(idxRegBase != X86_GREG_xSP /*SIB*/); 8920 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 8921 if (f64Bit || idxRegRet >= 8 || idxRegBase >= 8) 8922 pbCodeBuf[off++] = (idxRegRet >= 8 ? X86_OP_REX_R : 0) 8923 | (idxRegBase >= 8 ? X86_OP_REX_B : 0) 8924 | (f64Bit ? X86_OP_REX_W : 0); 8925 pbCodeBuf[off++] = 0x8d; 8926 uint8_t const bMod = (int8_t)u32EffAddr == (int32_t)u32EffAddr ? X86_MOD_MEM1 : X86_MOD_MEM4; 8927 if (idxRegBase != X86_GREG_x12 /*SIB*/) 8928 pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, idxRegBase & 7); 8929 else 8930 { 8931 pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, 4 /*SIB*/); 8932 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_x12 & 7, 4 /*no index*/, 0); 8933 } 8934 pbCodeBuf[off++] = RT_BYTE1(u32EffAddr); 8935 if (bMod == X86_MOD_MEM4) 8936 { 8937 pbCodeBuf[off++] = RT_BYTE2(u32EffAddr); 8938 pbCodeBuf[off++] = RT_BYTE3(u32EffAddr); 8939 pbCodeBuf[off++] = RT_BYTE4(u32EffAddr); 8940 } 8941 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 8942 } 8943 } 8944 else 8945 { 8946 Assert(idxRegIndex != X86_GREG_xSP /*no-index*/); 8947 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 8948 if (idxRegBase == UINT8_MAX) 8949 { 8950 /* lea ret, [(index64 << cShiftIndex) + disp32] */ 8951 if (f64Bit || idxRegRet >= 8 || idxRegIndex >= 8) 8952 pbCodeBuf[off++] = (idxRegRet >= 8 ? X86_OP_REX_R : 0) 8953 | (idxRegIndex >= 8 ? X86_OP_REX_X : 0) 8954 | (f64Bit ? X86_OP_REX_W : 0); 8955 pbCodeBuf[off++] = 0x8d; 8956 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, idxRegRet & 7, 4 /*SIB*/); 8957 pbCodeBuf[off++] = X86_SIB_MAKE(5 /*nobase/bp*/, idxRegIndex & 7, cShiftIndex); 8958 pbCodeBuf[off++] = RT_BYTE1(u32EffAddr); 8959 pbCodeBuf[off++] = RT_BYTE2(u32EffAddr); 8960 pbCodeBuf[off++] = RT_BYTE3(u32EffAddr); 8961 pbCodeBuf[off++] = RT_BYTE4(u32EffAddr); 8962 } 8963 else 8964 { 8965 /* lea ret, [(index64 << cShiftIndex) + base64 (+ disp32)] */ 8966 if (f64Bit || idxRegRet >= 8 || idxRegBase >= 8 || idxRegIndex >= 8) 8967 pbCodeBuf[off++] = (idxRegRet >= 8 ? X86_OP_REX_R : 0) 8968 | (idxRegBase >= 8 ? X86_OP_REX_B : 0) 8969 | (idxRegIndex >= 8 ? X86_OP_REX_X : 0) 8970 | (f64Bit ? X86_OP_REX_W : 0); 8971 pbCodeBuf[off++] = 0x8d; 8972 uint8_t const bMod = u32EffAddr == 0 && (idxRegBase & 7) != X86_GREG_xBP ? X86_MOD_MEM0 8973 : (int8_t)u32EffAddr == (int32_t)u32EffAddr ? X86_MOD_MEM1 : X86_MOD_MEM4; 8974 pbCodeBuf[off++] = X86_MODRM_MAKE(bMod, idxRegRet & 7, 4 /*SIB*/); 8975 pbCodeBuf[off++] = X86_SIB_MAKE(idxRegBase & 7, idxRegIndex & 7, cShiftIndex); 8976 if (bMod != X86_MOD_MEM0) 8977 { 8978 pbCodeBuf[off++] = RT_BYTE1(u32EffAddr); 8979 if (bMod == X86_MOD_MEM4) 8980 { 8981 pbCodeBuf[off++] = RT_BYTE2(u32EffAddr); 8982 pbCodeBuf[off++] = RT_BYTE3(u32EffAddr); 8983 pbCodeBuf[off++] = RT_BYTE4(u32EffAddr); 8984 } 8985 } 8986 } 8987 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 8988 } 8989 8990 if (!bFinalAdj) 8991 { /* likely */ } 8992 else 8993 { 8994 Assert(f64Bit); 8995 off = iemNativeEmitAddGprImm8(pReNative, off, idxRegRet, bFinalAdj); 8996 } 8997 8998 #elif defined(RT_ARCH_ARM64) 8999 if (i64EffAddr == 0) 9000 { 9001 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 9002 if (idxRegIndex == UINT8_MAX) 9003 pu32CodeBuf[off++] = Armv8A64MkInstrMov(idxRegRet, idxRegBase, f64Bit); 9004 else if (idxRegBase != UINT8_MAX) 9005 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegBase, idxRegIndex, 9006 f64Bit, false /*fSetFlags*/, cShiftIndex); 9007 else 9008 { 9009 Assert(cShiftIndex != 0); /* See base = index swap above when shift is 0 and we have no base reg. */ 9010 pu32CodeBuf[off++] = Armv8A64MkInstrLslImm(idxRegRet, idxRegIndex, cShiftIndex, f64Bit); 9011 } 9012 } 9013 else 9014 { 9015 if (f64Bit) 9016 { /* likely */ } 9017 else 9018 i64EffAddr = (int32_t)i64EffAddr; 9019 9020 if (i64EffAddr < 4096 && i64EffAddr >= 0 && idxRegBase != UINT8_MAX) 9021 { 9022 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 9023 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, idxRegRet, idxRegBase, i64EffAddr, f64Bit); 9024 } 9025 else if (i64EffAddr > -4096 && i64EffAddr < 0 && idxRegBase != UINT8_MAX) 9026 { 9027 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 9028 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, idxRegRet, idxRegBase, (uint32_t)-i64EffAddr, f64Bit); 9029 } 9030 else 9031 { 9032 if (f64Bit) 9033 off = iemNativeEmitLoadGprImm64(pReNative, off, idxRegRet, i64EffAddr); 9034 else 9035 off = iemNativeEmitLoadGprImm64(pReNative, off, idxRegRet, (uint32_t)i64EffAddr); 9036 if (idxRegBase != UINT8_MAX) 9037 { 9038 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 9039 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegRet, idxRegBase, f64Bit); 9040 } 9041 } 9042 if (idxRegIndex != UINT8_MAX) 9043 { 9044 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 9045 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, idxRegRet, idxRegRet, idxRegIndex, 9046 f64Bit, false /*fSetFlags*/, cShiftIndex); 9047 } 9048 } 9049 9050 #else 9051 # error "port me" 9052 #endif 9053 9054 if (idxRegIndex != UINT8_MAX) 9055 iemNativeRegFreeTmp(pReNative, idxRegIndex); 9056 if (idxRegBase != UINT8_MAX) 9057 iemNativeRegFreeTmp(pReNative, idxRegBase); 9058 return off; 9059 } 9060 8738 9061 8739 9062 … … 9280 9603 (uintptr_t)iemNativeHlpMemFlatStoreDataU32, pCallEntry->idxInstr) 9281 9604 9282 #define IEM_MC_STORE_MEM_FLAT_U64_CONST( _GCPtrMem, a_u64ConstValue) \9605 #define IEM_MC_STORE_MEM_FLAT_U64_CONST(a_GCPtrMem, a_u64ConstValue) \ 9283 9606 off = iemNativeEmitMemStoreConstDataCommon(pReNative, off, a_u64ConstValue, UINT8_MAX, a_GCPtrMem, sizeof(uint64_t), \ 9284 9607 (uintptr_t)iemNativeHlpMemFlatStoreDataU64, pCallEntry->idxInstr) … … 10125 10448 uint32_t offRange = 0; 10126 10449 uint32_t offOpcodes = 0; 10450 uint32_t const cbOpcodes = pTb->cbOpcodes; 10127 10451 RTGCPHYS GCPhysPc = pTb->GCPhysPc; 10128 10452 uint32_t const cDbgEntries = pDbgInfo->cEntries; … … 10162 10486 of ranges, or when some complicated interrupts/FFs are found to be pending or 10163 10487 similar. So, we just deal with it here rather than in the compiler code as it 10164 is a lot simpler to do uphere. */10488 is a lot simpler to do here. */ 10165 10489 if ( idxRange == UINT8_MAX 10166 10490 || idxRange >= cRanges … … 10169 10493 idxRange += 1; 10170 10494 if (idxRange < cRanges) 10171 offRange = 0;10495 offRange = !idxRange ? 0 : offRange - pTb->aRanges[idxRange - 1].cbOpcodes; 10172 10496 else 10173 10497 continue; 10174 Assert(offOpcodes == pTb->aRanges[idxRange].offOpcodes );10498 Assert(offOpcodes == pTb->aRanges[idxRange].offOpcodes + offRange); 10175 10499 GCPhysPc = pTb->aRanges[idxRange].offPhysPage 10176 10500 + (pTb->aRanges[idxRange].idxPhysPage == 0 … … 10180 10504 idxRange, GCPhysPc, pTb->aRanges[idxRange].cbOpcodes, 10181 10505 pTb->aRanges[idxRange].idxPhysPage); 10506 GCPhysPc += offRange; 10182 10507 } 10183 10508 10184 10509 /* Disassemble the instruction. */ 10185 uint8_t const cbInstrMax = RT_MIN(pTb->aRanges[idxRange].cbOpcodes - offRange, 15); 10510 //uint8_t const cbInstrMax = RT_MIN(pTb->aRanges[idxRange].cbOpcodes - offRange, 15); 10511 uint8_t const cbInstrMax = RT_MIN(cbOpcodes - offRange, 15); 10186 10512 uint32_t cbInstr = 1; 10187 10513 int rc = DISInstrWithPrefetchedBytes(GCPhysPc, enmGstCpuMode, DISOPTYPE_ALL, … … 10221 10547 case kIemTbDbgEntryType_ThreadedCall: 10222 10548 pHlp->pfnPrintf(pHlp, 10223 " Call #%u to %s (%u args) %s\n",10549 " Call #%u to %s (%u args) - %s\n", 10224 10550 idxThreadedCall, 10225 10551 g_apszIemThreadedFunctions[pDbgInfo->aEntries[iDbgEntry].ThreadedCall.enmCall], 10226 10552 g_acIemThreadedFunctionUsedArgs[pDbgInfo->aEntries[iDbgEntry].ThreadedCall.enmCall], 10227 pDbgInfo->aEntries[iDbgEntry].ThreadedCall.fRecompiled ? " - recompiled" : "");10553 pDbgInfo->aEntries[iDbgEntry].ThreadedCall.fRecompiled ? "recompiled" : "todo"); 10228 10554 idxThreadedCall++; 10229 10555 continue; … … 10331 10657 uint32_t const uInfo = *(uint32_t const *)&Dis.Instr.ab[3]; 10332 10658 if (RT_HIWORD(uInfo) < kIemThreadedFunc_End) 10333 pHlp->pfnPrintf(pHlp, " %p: nop ; marker: call #%u to %s (%u args) %s\n",10659 pHlp->pfnPrintf(pHlp, " %p: nop ; marker: call #%u to %s (%u args) - %s\n", 10334 10660 pNativeCur, uInfo & 0x7fff, g_apszIemThreadedFunctions[RT_HIWORD(uInfo)], 10335 10661 g_acIemThreadedFunctionUsedArgs[RT_HIWORD(uInfo)], 10336 uInfo & 0x8000 ? " - recompiled" : "");10662 uInfo & 0x8000 ? "recompiled" : "todo"); 10337 10663 else 10338 10664 pHlp->pfnPrintf(pHlp, " %p: nop ; unknown marker: %#x (%d)\n", pNativeCur, uInfo, uInfo); … … 10417 10743 i, GCPhysPc, pTb->aRanges[i].cbOpcodes, pTb->aRanges[i].idxPhysPage); 10418 10744 unsigned off = pTb->aRanges[i].offOpcodes; 10745 /** @todo this ain't working when crossing pages! */ 10419 10746 unsigned const cbOpcodes = pTb->aRanges[i].cbOpcodes + off; 10420 10747 while (off < cbOpcodes) … … 10460 10787 uint32_t const uInfo = *(uint32_t const *)&Dis.Instr.ab[3]; 10461 10788 if (RT_HIWORD(uInfo) < kIemThreadedFunc_End) 10462 pHlp->pfnPrintf(pHlp, "\n %p: nop ; marker: call #%u to %s (%u args) %s\n",10789 pHlp->pfnPrintf(pHlp, "\n %p: nop ; marker: call #%u to %s (%u args) - %s\n", 10463 10790 pNativeCur, uInfo & 0x7fff, g_apszIemThreadedFunctions[RT_HIWORD(uInfo)], 10464 10791 g_acIemThreadedFunctionUsedArgs[RT_HIWORD(uInfo)], 10465 uInfo & 0x8000 ? " - recompiled" : "");10792 uInfo & 0x8000 ? "recompiled" : "todo"); 10466 10793 else 10467 10794 pHlp->pfnPrintf(pHlp, " %p: nop ; unknown marker: %#x (%d)\n", pNativeCur, uInfo, uInfo); … … 10625 10952 */ 10626 10953 Log2(("%u[%u]: %s%s\n", pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->idxInstr, 10627 g_apszIemThreadedFunctions[pCallEntry->enmFunction], pfnRecom ? " " : "(todo)"));10954 g_apszIemThreadedFunctions[pCallEntry->enmFunction], pfnRecom ? "(recompiled)" : "(todo)")); 10628 10955 if (pfnRecom) /** @todo stats on this. */ 10629 10956 { -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncs.cpp
r102011 r102510 537 537 * @param uSibAndRspOffset Two parts: 538 538 * - The first 8 bits make up the SIB byte. 539 * - The next 8 bits are the fixed RSP/ESP offse 539 * - The next 8 bits are the fixed RSP/ESP offset 540 540 * in case of a pop [xSP]. 541 541 * @param u32Disp The displacement byte/word/dword, if any. -
trunk/src/VBox/VMM/include/IEMMc.h
r102471 r102510 979 979 iemMemFlatFetchDataR80Jmp(pVCpu, &(a_r80Dst), (a_GCPtrMem)) 980 980 # define IEM_MC_FETCH_MEM_FLAT_D80(a_d80Dst, a_GCPtrMem) \ 981 iemMemF etchDataD80Jmp(pVCpu, &(a_d80Dst), UINT8_MAX, (a_GCPtrMem))981 iemMemFlatFetchDataD80Jmp(pVCpu, &(a_d80Dst), (a_GCPtrMem)) 982 982 #endif 983 983 … … 1078 1078 (a_XmmDst).au32[(a_iDWord)] = iemMemFlatFetchDataU32Jmp(pVCpu, (a_GCPtrMem)) 1079 1079 # define IEM_MC_FETCH_MEM_FLAT_XMM_U64(a_XmmDst, a_iQWord, a_GCPtrMem) \ 1080 (a_XmmDst).au64[(a_iQWord)] = iemMemF etchDataU64Jmp(pVCpu, UINT8_MAX, (a_GCPtrMem))1080 (a_XmmDst).au64[(a_iQWord)] = iemMemFlatFetchDataU64Jmp(pVCpu, (a_GCPtrMem)) 1081 1081 1082 1082 # define IEM_MC_FETCH_MEM_U128_AND_XREG_U128(a_Dst, a_iXReg1, a_iSeg2, a_GCPtrMem2) do { \ -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r102447 r102510 105 105 *********************************************************************************************************************************/ 106 106 107 #ifdef RT_ARCH_AMD64 108 /** 109 * Common bit of iemNativeEmitLoadGprByGpr and friends. 110 */ 111 DECL_FORCE_INLINE(uint32_t) 112 iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint8_t iGprBase, int32_t offDisp) 113 { 114 if (offDisp == 0 && (iGprBase & 7) != X86_GREG_xBP) /* Can use encoding w/o displacement field. */ 115 { 116 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, iGprReg & 7, iGprBase & 7); 117 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 118 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 119 } 120 else if (offDisp == (int8_t)offDisp) 121 { 122 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7); 123 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 124 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 125 pbCodeBuf[off++] = (uint8_t)offDisp; 126 } 127 else 128 { 129 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, iGprReg & 7, iGprBase & 7); 130 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 131 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 132 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 133 pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp); 134 pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp); 135 pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp); 136 } 137 return off; 138 } 139 #endif /* RT_ARCH_AMD64 */ 140 107 141 /** 108 142 * Emits setting a GPR to zero. … … 889 923 /** 890 924 * Sign-extends 8-bit value in @a iGprSrc into a 32-bit value in @a iGprDst. 891 * @note Bits 6 4thru 32 are cleared.925 * @note Bits 63 thru 32 are cleared. 892 926 */ 893 927 DECL_INLINE_THROW(uint32_t) … … 918 952 /** 919 953 * Sign-extends 8-bit value in @a iGprSrc into a 16-bit value in @a iGprDst. 920 * @note Bits 6 4thru 16 are cleared.954 * @note Bits 63 thru 16 are cleared. 921 955 */ 922 956 DECL_INLINE_THROW(uint32_t) … … 957 991 /** 958 992 * Emits a gprdst = gprsrc + addend load. 959 */ 993 * @note The added is 32-bit for AMD64 and 64-bit for ARM64. 994 */ 995 #ifdef RT_ARCH_AMD64 960 996 DECL_INLINE_THROW(uint32_t) 961 997 iemNativeEmitLoadGprFromGprWithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off, … … 964 1000 Assert(iAddend != 0); 965 1001 966 #ifdef RT_ARCH_AMD64967 1002 /* lea gprdst, [gprsrc + iAddend] */ 968 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 969 if ((iGprDst | iGprSrc) >= 8) 970 pbCodeBuf[off++] = iGprDst < 8 ? X86_OP_REX_W | X86_OP_REX_B 971 : iGprSrc >= 8 ? X86_OP_REX_W | X86_OP_REX_R | X86_OP_REX_B 972 : X86_OP_REX_W | X86_OP_REX_R; 973 else 974 pbCodeBuf[off++] = X86_OP_REX_W; 1003 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8); 1004 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst >= 8 ? X86_OP_REX_R : 0) | (iGprSrc >= 8 ? X86_OP_REX_B : 0); 975 1005 pbCodeBuf[off++] = 0x8d; 976 if (iAddend >= -128 && iAddend < 128) 977 { 978 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprDst & 7, iGprSrc & 7); 979 pbCodeBuf[off++] = (int8_t)iAddend; 980 } 981 else 982 { 983 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM4, iGprDst & 7, iGprSrc & 7); 984 pbCodeBuf[off++] = RT_BYTE1((uint32_t)iAddend); 985 pbCodeBuf[off++] = RT_BYTE2((uint32_t)iAddend); 986 pbCodeBuf[off++] = RT_BYTE3((uint32_t)iAddend); 987 pbCodeBuf[off++] = RT_BYTE4((uint32_t)iAddend); 988 } 989 990 #elif defined(RT_ARCH_ARM64) 1006 off = iemNativeEmitGprByGprDisp(pbCodeBuf, off, iGprDst, iGprSrc, iAddend); 1007 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1008 return off; 1009 } 1010 1011 #elif defined(RT_ARCH_ARM64) 1012 DECL_INLINE_THROW(uint32_t) 1013 iemNativeEmitLoadGprFromGprWithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1014 uint8_t iGprDst, uint8_t iGprSrc, int64_t iAddend) 1015 { 991 1016 if ((uint32_t)iAddend < 4096) 992 1017 { … … 1003 1028 else 1004 1029 { 1030 Assert(iGprSrc != iGprDst); 1031 off = iemNativeEmitLoadGprImm64(pReNative, off, iGprDst, iAddend); 1032 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1033 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst); 1034 } 1035 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1036 return off; 1037 } 1038 #else 1039 # error "port me" 1040 #endif 1041 1042 /** 1043 * Emits a gprdst = gprsrc + addend load, accepting iAddend == 0. 1044 * @note The added is 32-bit for AMD64 and 64-bit for ARM64. 1045 */ 1046 #ifdef RT_ARCH_AMD64 1047 DECL_INLINE_THROW(uint32_t) 1048 iemNativeEmitLoadGprFromGprWithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1049 uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend) 1050 #else 1051 DECL_INLINE_THROW(uint32_t) 1052 iemNativeEmitLoadGprFromGprWithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1053 uint8_t iGprDst, uint8_t iGprSrc, int64_t iAddend) 1054 #endif 1055 { 1056 if (iAddend != 0) 1057 return iemNativeEmitLoadGprFromGprWithAddend(pReNative, off, iGprDst, iGprSrc, iAddend); 1058 return iemNativeEmitLoadGprFromGpr(pReNative, off, iGprDst, iGprSrc); 1059 } 1060 1061 1062 /** 1063 * Emits a gprdst = gprsrc32 + addend load. 1064 * @note Bits 63 thru 32 are cleared. 1065 */ 1066 DECL_INLINE_THROW(uint32_t) 1067 iemNativeEmitLoadGprFromGpr32WithAddend(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1068 uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend) 1069 { 1070 Assert(iAddend != 0); 1071 1072 #ifdef RT_ARCH_AMD64 1073 /* a32 o32 lea gprdst, [gprsrc + iAddend] */ 1074 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 9); 1075 pbCodeBuf[off++] = X86_OP_PRF_SIZE_ADDR; 1076 if ((iGprDst | iGprSrc) >= 8) 1077 pbCodeBuf[off++] = (iGprDst >= 8 ? X86_OP_REX_R : 0) | (iGprSrc >= 8 ? X86_OP_REX_B : 0); 1078 pbCodeBuf[off++] = 0x8d; 1079 off = iemNativeEmitGprByGprDisp(pbCodeBuf, off, iGprDst, iGprSrc, iAddend); 1080 1081 #elif defined(RT_ARCH_ARM64) 1082 if ((uint32_t)iAddend < 4096) 1083 { 1084 /* add dst, src, uimm12 */ 1085 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1086 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(false /*fSub*/, iGprDst, iGprSrc, (uint32_t)iAddend, false /*f64Bit*/); 1087 } 1088 else if ((uint32_t)-iAddend < 4096) 1089 { 1090 /* sub dst, src, uimm12 */ 1091 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1092 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, iGprDst, iGprSrc, (uint32_t)-iAddend, false /*f64Bit*/); 1093 } 1094 else 1095 { 1096 Assert(iGprSrc != iGprDst); 1005 1097 off = iemNativeEmitLoadGprImm64(pReNative, off, iGprDst, (int64_t)iAddend); 1006 1098 uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 1007 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst); 1008 } 1009 1010 #else 1011 # error "port me" 1012 #endif 1013 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1014 return off; 1015 } 1099 pu32CodeBuf[off++] = Armv8A64MkInstrAddSubReg(false /*fSub*/, iGprDst, iGprSrc, iGprDst, false /*f64Bit*/); 1100 } 1101 1102 #else 1103 # error "port me" 1104 #endif 1105 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1106 return off; 1107 } 1108 1109 1110 /** 1111 * Emits a gprdst = gprsrc32 + addend load, accepting iAddend == 0. 1112 */ 1113 DECL_INLINE_THROW(uint32_t) 1114 iemNativeEmitLoadGprFromGpr32WithAddendMaybeZero(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1115 uint8_t iGprDst, uint8_t iGprSrc, int32_t iAddend) 1116 { 1117 if (iAddend != 0) 1118 return iemNativeEmitLoadGprFromGpr32WithAddend(pReNative, off, iGprDst, iGprSrc, iAddend); 1119 return iemNativeEmitLoadGprFromGpr32(pReNative, off, iGprDst, iGprSrc); 1120 } 1121 1016 1122 1017 1123 … … 1319 1425 1320 1426 1321 #ifdef RT_ARCH_AMD64 1322 /** 1323 * Common bit of iemNativeEmitLoadGprByGpr and friends. 1324 */ 1325 DECL_FORCE_INLINE(uint32_t) 1326 iemNativeEmitGprByGprDisp(uint8_t *pbCodeBuf, uint32_t off, uint8_t iGprReg, uint8_t iGprBase, int32_t offDisp) 1327 { 1328 if (offDisp == 0 && (iGprBase & 7) != X86_GREG_xBP) /* Can use encoding w/o displacement field. */ 1329 { 1330 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM0, iGprReg & 7, iGprBase & 7); 1331 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 1332 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 1333 } 1334 else if (offDisp == (int8_t)offDisp) 1335 { 1336 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7); 1337 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 1338 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 1339 pbCodeBuf[off++] = (uint8_t)offDisp; 1340 } 1341 else 1342 { 1343 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_MEM1, iGprReg & 7, iGprBase & 7); 1344 if ((iGprBase & 7) == X86_GREG_xSP) /* for RSP/R12 relative addressing we have to use a SIB byte. */ 1345 pbCodeBuf[off++] = X86_SIB_MAKE(X86_GREG_xSP, X86_GREG_xSP, 0); /* -> [RSP/R12] */ 1346 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 1347 pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp); 1348 pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp); 1349 pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp); 1350 } 1351 return off; 1352 } 1353 #elif defined(RT_ARCH_ARM64) 1427 #if defined(RT_ARCH_ARM64) 1354 1428 /** 1355 1429 * Common bit of iemNativeEmitLoadGprFromVCpuU64 and friends.
Note:
See TracChangeset
for help on using the changeset viewer.