Changeset 102699 in vbox for trunk/src/VBox/VMM/include
- Timestamp:
- Dec 25, 2023 10:22:01 PM (14 months ago)
- Location:
- trunk/src/VBox/VMM/include
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r102684 r102699 814 814 bool fPreferVolatile = true); 815 815 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpForGuestReg(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 816 IEMNATIVEGSTREG enmGstReg, IEMNATIVEGSTREGUSE enmIntendedUse); 816 IEMNATIVEGSTREG enmGstReg, IEMNATIVEGSTREGUSE enmIntendedUse, 817 bool fNoVoltileRegs = false); 817 818 DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpForGuestRegIfAlreadyPresent(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, 818 819 IEMNATIVEGSTREG enmGstReg); -
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r102662 r102699 2903 2903 * Emits a Jcc rel32 / B.cc imm19 with a fixed displacement. 2904 2904 * 2905 * The @a offTarget is applied x86-style, so zero means the next instruction. 2906 * The unit is IEMNATIVEINSTR. 2907 */ 2908 DECL_INLINE_THROW(uint32_t) 2909 iemNativeEmitJccToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget, IEMNATIVEINSTRCOND enmCond) 2910 { 2911 #ifdef RT_ARCH_AMD64 2912 /* jcc rel32 */ 2905 * @note The @a offTarget is the absolute jump target (unit is IEMNATIVEINSTR). 2906 * 2907 * Only use hardcoded jumps forward when emitting for exactly one 2908 * platform, otherwise apply iemNativeFixupFixedJump() to ensure hitting 2909 * the right target address on all platforms! 2910 * 2911 * Please also note that on x86 it is necessary pass off + 256 or higher 2912 * for @a offTarget one believe the intervening code is more than 127 2913 * bytes long. 2914 */ 2915 DECL_INLINE_THROW(uint32_t) 2916 iemNativeEmitJccToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget, IEMNATIVEINSTRCOND enmCond) 2917 { 2918 #ifdef RT_ARCH_AMD64 2919 /* jcc rel8 / rel32 */ 2913 2920 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6); 2914 if (offTarget < 128 && offTarget >= -128) 2921 int32_t offDisp = (int32_t)(offTarget - (off + 2)); 2922 if (offDisp < 128 && offDisp >= -128) 2915 2923 { 2916 2924 pbCodeBuf[off++] = (uint8_t)enmCond | 0x70; 2917 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offTarget); 2918 } 2919 else 2920 { 2925 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 2926 } 2927 else 2928 { 2929 offDisp -= 4; 2921 2930 pbCodeBuf[off++] = 0x0f; 2922 2931 pbCodeBuf[off++] = (uint8_t)enmCond | 0x80; 2923 pbCodeBuf[off++] = RT_BYTE1((uint32_t)off Target);2924 pbCodeBuf[off++] = RT_BYTE2((uint32_t)off Target);2925 pbCodeBuf[off++] = RT_BYTE3((uint32_t)off Target);2926 pbCodeBuf[off++] = RT_BYTE4((uint32_t)off Target);2932 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 2933 pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp); 2934 pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp); 2935 pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp); 2927 2936 } 2928 2937 2929 2938 #elif defined(RT_ARCH_ARM64) 2930 2939 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 2931 pu32CodeBuf[off++] = Armv8A64MkInstrBCond(enmCond, offTarget + 1);2940 pu32CodeBuf[off++] = Armv8A64MkInstrBCond(enmCond, (int32_t)(offTarget - off)); 2932 2941 2933 2942 #else … … 2942 2951 * Emits a JZ/JE rel32 / B.EQ imm19 with a fixed displacement. 2943 2952 * 2944 * The @a offTarget is applied x86-style, so zero means the next instruction. 2945 * The unit is IEMNATIVEINSTR. 2946 */ 2947 DECL_INLINE_THROW(uint32_t) iemNativeEmitJzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2953 * See notes on @a offTarget in the iemNativeEmitJccToFixed() documentation. 2954 */ 2955 DECL_INLINE_THROW(uint32_t) iemNativeEmitJzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget) 2948 2956 { 2949 2957 #ifdef RT_ARCH_AMD64 … … 2960 2968 * Emits a JNZ/JNE rel32 / B.NE imm19 with a fixed displacement. 2961 2969 * 2962 * The @a offTarget is applied x86-style, so zero means the next instruction. 2963 * The unit is IEMNATIVEINSTR. 2964 */ 2965 DECL_INLINE_THROW(uint32_t) iemNativeEmitJnzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2970 * See notes on @a offTarget in the iemNativeEmitJccToFixed() documentation. 2971 */ 2972 DECL_INLINE_THROW(uint32_t) iemNativeEmitJnzToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget) 2966 2973 { 2967 2974 #ifdef RT_ARCH_AMD64 … … 2978 2985 * Emits a JBE/JNA rel32 / B.LS imm19 with a fixed displacement. 2979 2986 * 2980 * The @a offTarget is applied x86-style, so zero means the next instruction. 2981 * The unit is IEMNATIVEINSTR. 2982 */ 2983 DECL_INLINE_THROW(uint32_t) iemNativeEmitJbeToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 2987 * See notes on @a offTarget in the iemNativeEmitJccToFixed() documentation. 2988 */ 2989 DECL_INLINE_THROW(uint32_t) iemNativeEmitJbeToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget) 2984 2990 { 2985 2991 #ifdef RT_ARCH_AMD64 … … 2996 3002 * Emits a JA/JNBE rel32 / B.HI imm19 with a fixed displacement. 2997 3003 * 2998 * The @a offTarget is applied x86-style, so zero means the next instruction. 2999 * The unit is IEMNATIVEINSTR. 3000 */ 3001 DECL_INLINE_THROW(uint32_t) iemNativeEmitJaToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, int32_t offTarget) 3004 * See notes on @a offTarget in the iemNativeEmitJccToFixed() documentation. 3005 */ 3006 DECL_INLINE_THROW(uint32_t) iemNativeEmitJaToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget) 3002 3007 { 3003 3008 #ifdef RT_ARCH_AMD64 … … 3012 3017 3013 3018 /** 3019 * Emits a JMP rel32/rel8 / B imm26 with a fixed displacement. 3020 * 3021 * See notes on @a offTarget in the iemNativeEmitJccToFixed() documentation. 3022 */ 3023 DECL_INLINE_THROW(uint32_t) iemNativeEmitJmpToFixed(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t offTarget) 3024 { 3025 #ifdef RT_ARCH_AMD64 3026 /* jmp rel8 or rel32 */ 3027 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); 3028 int32_t offDisp = offTarget - (off + 2); 3029 if (offDisp < 128 && offDisp >= -128) 3030 { 3031 pbCodeBuf[off++] = 0xeb; 3032 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 3033 } 3034 else 3035 { 3036 offDisp -= 3; 3037 pbCodeBuf[off++] = 0xe9; 3038 pbCodeBuf[off++] = RT_BYTE1((uint32_t)offDisp); 3039 pbCodeBuf[off++] = RT_BYTE2((uint32_t)offDisp); 3040 pbCodeBuf[off++] = RT_BYTE3((uint32_t)offDisp); 3041 pbCodeBuf[off++] = RT_BYTE4((uint32_t)offDisp); 3042 } 3043 3044 #elif defined(RT_ARCH_ARM64) 3045 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 3046 pu32CodeBuf[off++] = Armv8A64MkInstrB(enmCond, (int32_t)(offTarget - off)); 3047 3048 #else 3049 # error "Port me!" 3050 #endif 3051 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 3052 return off; 3053 } 3054 3055 3056 /** 3014 3057 * Fixes up a conditional jump to a fixed label. 3015 * @see iemNativeEmitJnzToFixed, iemNativeEmitJzToFixed, ... 3016 */ 3017 DECLINLINE(void) iemNativeFixupFixedJump(PIEMRECOMPILERSTATE pReNative, uint32_t offFixup, uint32_t offTarget) 3018 { 3019 # if defined(RT_ARCH_AMD64) 3058 * @see iemNativeEmitJmpToFixed, iemNativeEmitJnzToFixed, 3059 * iemNativeEmitJzToFixed, ... 3060 */ 3061 DECL_INLINE_THROW(void) iemNativeFixupFixedJump(PIEMRECOMPILERSTATE pReNative, uint32_t offFixup, uint32_t offTarget) 3062 { 3063 #ifdef RT_ARCH_AMD64 3020 3064 uint8_t * const pbCodeBuf = pReNative->pInstrBuf; 3021 if (pbCodeBuf[offFixup] != 0x0f)3022 {3023 Assert((uint8_t)(pbCodeBuf[offFixup] - 0x70) <= 0x10);3065 uint8_t const bOpcode = pbCodeBuf[offFixup]; 3066 if ((uint8_t)(bOpcode - 0x70) < (uint8_t)0x10 || bOpcode == 0xeb) 3067 { 3024 3068 pbCodeBuf[offFixup + 1] = (uint8_t)(offTarget - (offFixup + 2)); 3025 Assert(pbCodeBuf[offFixup + 1] == offTarget - (offFixup + 2)); 3026 } 3027 else 3028 { 3029 Assert((uint8_t)(pbCodeBuf[offFixup + 1] - 0x80) <= 0x10); 3030 uint32_t const offRel32 = offTarget - (offFixup + 6); 3031 pbCodeBuf[offFixup + 2] = RT_BYTE1(offRel32); 3032 pbCodeBuf[offFixup + 3] = RT_BYTE2(offRel32); 3033 pbCodeBuf[offFixup + 4] = RT_BYTE3(offRel32); 3034 pbCodeBuf[offFixup + 5] = RT_BYTE4(offRel32); 3035 } 3036 3037 # elif defined(RT_ARCH_ARM64) 3069 AssertStmt(pbCodeBuf[offFixup + 1] == offTarget - (offFixup + 2), 3070 IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_EMIT_FIXED_JUMP_OUT_OF_RANGE)); 3071 } 3072 else 3073 { 3074 if (bOpcode != 0x0f) 3075 Assert(bOpcode == 0xe9); 3076 else 3077 { 3078 offFixup += 1; 3079 Assert((uint8_t)(pbCodeBuf[offFixup] - 0x80) <= 0x10); 3080 } 3081 uint32_t const offRel32 = offTarget - (offFixup + 5); 3082 pbCodeBuf[offFixup + 1] = RT_BYTE1(offRel32); 3083 pbCodeBuf[offFixup + 2] = RT_BYTE2(offRel32); 3084 pbCodeBuf[offFixup + 3] = RT_BYTE3(offRel32); 3085 pbCodeBuf[offFixup + 4] = RT_BYTE4(offRel32); 3086 } 3087 3088 #elif defined(RT_ARCH_ARM64) 3038 3089 uint32_t * const pu32CodeBuf = pReNative->pInstrBuf; 3039 3040 int32_t const offDisp = offTarget - offFixup; 3041 Assert(offDisp >= -262144 && offDisp < 262144); 3042 Assert((pu32CodeBuf[offFixup] & UINT32_C(0xff000000)) == UINT32_C(0x54000000)); /* B.COND + BC.COND */ 3043 3044 pu32CodeBuf[offFixup] = (pu32CodeBuf[offFixup] & UINT32_C(0xff00001f)) 3045 | (((uint32_t)offDisp & UINT32_C(0x0007ffff)) << 5); 3046 3047 # endif 3090 if ((pu32CodeBuf[offFixup] & UINT32_C(0xff000000)) == UINT32_C(0x54000000)) 3091 { 3092 /* B.COND + BC.COND */ 3093 int32_t const offDisp = offTarget - offFixup; 3094 Assert(offDisp >= -262144 && offDisp < 262144); 3095 pu32CodeBuf[offFixup] = (pu32CodeBuf[offFixup] & UINT32_C(0xff00001f)) 3096 | (((uint32_t)offDisp & UINT32_C(0x0007ffff)) << 5); 3097 } 3098 else 3099 { 3100 /* B imm26 */ 3101 Assert((pu32CodeBuf[offFixup] & UINT32_C(0xfc000000)) == UINT32_C(0x14000000)); 3102 int32_t const offDisp = offTarget - offFixup; 3103 Assert(offDisp >= -33554432 && offDisp < 33554432); 3104 pu32CodeBuf[offFixup] = (pu32CodeBuf[offFixup] & UINT32_C(0xfc000000)) 3105 | ((uint32_t)offDisp & UINT32_C(0x03ffffff)); 3106 } 3107 3108 #else 3109 # error "Port me!" 3110 #endif 3048 3111 } 3049 3112 … … 3327 3390 3328 3391 /** 3392 * Emits code that jumps to @a idxLabel if @a iGprSrc is not zero. 3393 * 3394 * The operand size is given by @a f64Bit. 3395 */ 3396 DECL_INLINE_THROW(uint32_t) iemNativeEmitTestIfGprIsNotZeroAndJmpToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, 3397 uint8_t iGprSrc, bool f64Bit, uint32_t idxLabel) 3398 { 3399 Assert(idxLabel < pReNative->cLabels); 3400 3401 #ifdef RT_ARCH_AMD64 3402 /* test reg32,reg32 / test reg64,reg64 */ 3403 uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3); 3404 if (f64Bit) 3405 pbCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_R | X86_OP_REX_B); 3406 else if (iGprSrc >= 8) 3407 pbCodeBuf[off++] = X86_OP_REX_R | X86_OP_REX_B; 3408 pbCodeBuf[off++] = 0x85; 3409 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, iGprSrc & 7, iGprSrc & 7); 3410 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 3411 3412 /* jnz idxLabel */ 3413 off = iemNativeEmitJnzToLabel(pReNative, off, idxLabel); 3414 3415 #elif defined(RT_ARCH_ARM64) 3416 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 3417 iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm19At5); 3418 pu32CodeBuf[off++] = Armv8A64MkInstrCbzCbnz(true /*fJmpIfNotZero*/, 0, iGprSrc, f64Bit); 3419 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 3420 3421 #else 3422 # error "Port me!" 3423 #endif 3424 return off; 3425 } 3426 3427 3428 /** 3429 * Emits code that jumps to a new label if @a iGprSrc is not zero. 3430 * 3431 * The operand size is given by @a f64Bit. 3432 */ 3433 DECL_INLINE_THROW(uint32_t) 3434 iemNativeEmitTestIfGprIsNotZeroAndJmpToNewLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprSrc, bool f64Bit, 3435 IEMNATIVELABELTYPE enmLabelType, uint16_t uData = 0) 3436 { 3437 uint32_t const idxLabel = iemNativeLabelCreate(pReNative, enmLabelType, UINT32_MAX /*offWhere*/, uData); 3438 return iemNativeEmitTestIfGprIsNotZeroAndJmpToLabel(pReNative, off, iGprSrc, f64Bit, idxLabel); 3439 } 3440 3441 3442 /** 3329 3443 * Emits code that jumps to the given label if @a iGprLeft and @a iGprRight 3330 3444 * differs.
Note:
See TracChangeset
for help on using the changeset viewer.