Changeset 103728 in vbox for trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
- Timestamp:
- Mar 7, 2024 12:11:33 PM (13 months ago)
- svn:sync-xref-src-repo-rev:
- 162096
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r103671 r103728 157 157 * Mask GPRs with fixes assignments, either by us or dictated by the CPU/OS 158 158 * architecture. */ 159 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 160 /** @def IEMNATIVE_SIMD_REG_FIXED_TMP0 161 * Mask SIMD registers with fixes assignments, either by us or dictated by the CPU/OS 162 * architecture. */ 163 /** @def IEMNATIVE_SIMD_REG_FIXED_TMP0 164 * Dedicated temporary SIMD register. */ 165 #endif 159 166 #if defined(RT_ARCH_AMD64) && !defined(DOXYGEN_RUNNING) 160 167 # define IEMNATIVE_REG_FIXED_PVMCPU X86_GREG_xBX … … 164 171 | RT_BIT_32(X86_GREG_xSP) \ 165 172 | RT_BIT_32(X86_GREG_xBP) ) 173 174 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 175 # if defined(IEMNATIVE_WITH_SIMD_REG_ACCESS_ALL_REGISTERS) || !defined(_MSC_VER) 176 # define IEMNATIVE_SIMD_REG_FIXED_MASK 0 177 # else 178 /** On Windows xmm6 through xmm15 are marked as callee saved. */ 179 # define IEMNATIVE_SIMD_REG_FIXED_MASK (UINT32_C(0xffc0)) 180 # endif 181 # endif 166 182 167 183 #elif defined(RT_ARCH_ARM64) || defined(DOXYGEN_RUNNING) … … 186 202 | IEMNATIVE_REG_FIXED_MASK_ADD) 187 203 204 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 205 # define IEMNATIVE_SIMD_REG_FIXED_TMP0 ARMV8_A64_REG_Q30 206 # if defined(IEMNATIVE_WITH_SIMD_REG_ACCESS_ALL_REGISTERS) 207 # define IEMNATIVE_SIMD_REG_FIXED_MASK RT_BIT_32(ARMV8_A64_REG_Q30) 208 # else 209 /** arm64 declares the low 64-bit of v8-v15 as callee saved. */ 210 # define IEMNATIVE_SIMD_REG_FIXED_MASK ( UINT32_C(0xff00) \ 211 | RT_BIT_32(ARMV8_A64_REG_Q30)) 212 # endif 213 # endif 214 188 215 #else 189 216 # error "port me" … … 227 254 | RT_BIT_32(X86_GREG_x10) \ 228 255 | RT_BIT_32(X86_GREG_x11) ) 256 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 257 /* xmm0 - xmm5 are marked as volatile. */ 258 # define IEMNATIVE_CALL_VOLATILE_SIMD_REG_MASK (UINT32_C(0x3f)) 259 # endif 260 229 261 # else 230 262 # define IEMNATIVE_CALL_ARG_GREG_COUNT 6 … … 250 282 | RT_BIT_32(X86_GREG_x10) \ 251 283 | RT_BIT_32(X86_GREG_x11) ) 284 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 285 /* xmm0 - xmm15 are marked as volatile. */ 286 # define IEMNATIVE_CALL_VOLATILE_SIMD_REG_MASK (UINT32_C(0xffff)) 287 # endif 252 288 # endif 253 289 … … 289 325 | RT_BIT_32(ARMV8_A64_REG_X16) \ 290 326 | RT_BIT_32(ARMV8_A64_REG_X17) ) 327 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 328 /* The low 64 bits of v8 - v15 marked as callee saved but the rest is volatile, 329 * so to simplify our life a bit we just mark everything as volatile. */ 330 # define IEMNATIVE_CALL_VOLATILE_SIMD_REG_MASK (UINT32_C(0xffffffff)) 331 # endif 291 332 292 333 #endif … … 306 347 * Mask corresponding to IEMNATIVE_HST_GREG_COUNT that can be applied to 307 348 * inverted register masks and such to get down to a correct set of regs. */ 349 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 350 /** @def IEMNATIVE_HST_SIMD_REG_COUNT 351 * Number of host SIMD registers we track. */ 352 /** @def IEMNATIVE_HST_SIMD_REG_MASK 353 * Mask corresponding to IEMNATIVE_HST_SIMD_REG_COUNT that can be applied to 354 * inverted register masks and such to get down to a correct set of regs. */ 355 #endif 308 356 #ifdef RT_ARCH_AMD64 309 357 # define IEMNATIVE_HST_GREG_COUNT 16 310 358 # define IEMNATIVE_HST_GREG_MASK UINT32_C(0xffff) 311 359 360 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 361 # define IEMNATIVE_HST_SIMD_REG_COUNT 16 362 # define IEMNATIVE_HST_SIMD_REG_MASK UINT32_C(0xffff) 363 # endif 364 312 365 #elif defined(RT_ARCH_ARM64) 313 366 # define IEMNATIVE_HST_GREG_COUNT 32 314 367 # define IEMNATIVE_HST_GREG_MASK UINT32_MAX 368 369 # ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 370 # define IEMNATIVE_HST_SIMD_REG_COUNT 32 371 # define IEMNATIVE_HST_SIMD_REG_MASK UINT32_MAX 372 # endif 373 315 374 #else 316 375 # error "Port me!" … … 735 794 /** @} */ 736 795 796 797 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 798 /** 799 * Guest registers that can be shadowed in host SIMD registers. 800 * 801 * @todo r=aeichner Liveness tracking 802 * @todo r=aeichner Given that we can only track xmm/ymm here does this actually make sense? 803 */ 804 typedef enum IEMNATIVEGSTSIMDREG : uint8_t 805 { 806 kIemNativeGstSimdReg_SimdRegFirst = 0, 807 kIemNativeGstSimdReg_SimdRegLast = kIemNativeGstSimdReg_SimdRegFirst + 15, 808 kIemNativeGstSimdReg_End 809 } IEMNATIVEGSTSIMDREG; 810 811 /** @name Helpers for converting register numbers to IEMNATIVEGSTSIMDREG values. 812 * @{ */ 813 #define IEMNATIVEGSTSIMDREG_SIMD(a_iSimdReg) ((IEMNATIVEGSTSIMDREG)(kIemNativeGstSimdReg_SimdRegFirst + (a_iSimdReg))) 814 /** @} */ 815 816 /** 817 * The Load/store size for a SIMD guest register. 818 */ 819 typedef enum IEMNATIVEGSTSIMDREGLDSTSZ : uint8_t 820 { 821 /** Invalid size. */ 822 kIemNativeGstSimdRegLdStSz_Invalid = 0, 823 /** Loads the low 128-bit of a guest SIMD register. */ 824 kIemNativeGstSimdRegLdStSz_Low128, 825 /** Loads the high 128-bit of a guest SIMD register. */ 826 kIemNativeGstSimdRegLdStSz_High128, 827 /** Loads the whole 256-bits of a guest SIMD register. */ 828 kIemNativeGstSimdRegLdStSz_256, 829 /** End value. */ 830 kIemNativeGstSimdRegLdStSz_End 831 } IEMNATIVEGSTSIMDREGLDSTSZ; 832 #endif 833 834 737 835 /** 738 836 * Intended use statement for iemNativeRegAllocTmpForGuestReg(). … … 912 1010 913 1011 1012 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1013 /** 1014 * Host SIMD register entry - this tracks a virtual 256-bit register split into two 128-bit 1015 * halves, on architectures where there is no 256-bit register available this entry will track 1016 * two adjacent 128-bit host registers. 1017 * 1018 * The actual allocation status is kept in IEMRECOMPILERSTATE::bmHstSimdRegs. 1019 */ 1020 typedef struct IEMNATIVEHSTSIMDREG 1021 { 1022 /** Set of guest registers this one shadows. 1023 * 1024 * Using a bitmap here so we can designate the same host register as a copy 1025 * for more than one guest register. This is expected to be useful in 1026 * situations where one value is copied to several registers in a sequence. 1027 * If the mapping is 1:1, then we'd have to pick which side of a 'MOV SRC,DST' 1028 * sequence we'd want to let this register follow to be a copy of and there 1029 * will always be places where we'd be picking the wrong one. 1030 */ 1031 uint64_t fGstRegShadows; 1032 /** What is being kept in this register. */ 1033 IEMNATIVEWHAT enmWhat; 1034 /** Flag what is currently loaded, low 128-bits, high 128-bits or complete 256-bits. */ 1035 IEMNATIVEGSTSIMDREGLDSTSZ enmLoaded; 1036 /** Alignment padding. */ 1037 uint8_t abAlign[6]; 1038 } IEMNATIVEHSTSIMDREG; 1039 #endif 1040 1041 914 1042 /** 915 1043 * Core state for the native recompiler, that is, things that needs careful … … 935 1063 uint64_t bmGstRegShadows; 936 1064 1065 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1066 /** Allocation bitmap for aHstSimdRegs. */ 1067 uint32_t bmHstSimdRegs; 1068 1069 /** Bitmap marking which host SIMD register contains guest SIMD register shadow copies. 1070 * This is used during register allocation to try preserve copies. */ 1071 uint32_t bmHstSimdRegsWithGstShadow; 1072 /** Bitmap marking valid entries in aidxSimdGstRegShadows. */ 1073 uint64_t bmGstSimdRegShadows; 1074 /** Bitmap marking whether the low 128-bit of the shadowed guest register are dirty and need writeback. */ 1075 uint64_t bmGstSimdRegShadowDirtyLo128; 1076 /** Bitmap marking whether the high 128-bit of the shadowed guest register are dirty and need writeback. */ 1077 uint64_t bmGstSimdRegShadowDirtyHi128; 1078 #endif 1079 937 1080 union 938 1081 { … … 953 1096 * there are no duplicate copies or ambiguities like that). */ 954 1097 uint8_t aidxGstRegShadows[kIemNativeGstReg_End]; 1098 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1099 /** Maps a guest SIMD register to a host SIMD register (index by IEMNATIVEGSTSIMDREG). 1100 * Entries are only valid if the corresponding bit in bmGstSimdRegShadows is set. 1101 * (A shadow copy of a guest register can only be held in a one host register, 1102 * there are no duplicate copies or ambiguities like that). */ 1103 uint8_t aidxGstSimdRegShadows[kIemNativeGstSimdReg_End]; 1104 #endif 955 1105 956 1106 /** Host register allocation tracking. */ 957 1107 IEMNATIVEHSTREG aHstRegs[IEMNATIVE_HST_GREG_COUNT]; 1108 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1109 /** Host SIMD register allocation tracking. */ 1110 IEMNATIVEHSTSIMDREG aHstSimdRegs[IEMNATIVE_HST_SIMD_REG_COUNT]; 1111 #endif 958 1112 959 1113 /** Variables and arguments. */ … … 982 1136 # define IEMNATIVE_VAR_IDX_UNPACK(a_idxVar) (a_idxVar) 983 1137 # define IEMNATIVE_VAR_IDX_PACK(a_idxVar) (a_idxVar) 1138 #endif 1139 1140 1141 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1142 /** Clear the dirty state of the given guest SIMD register. */ 1143 # define IEMNATIVE_SIMD_REG_STATE_CLR_DIRTY(a_pReNative, a_iSimdReg) \ 1144 do { \ 1145 (a_pReNative)->Core.bmGstSimdRegShadowDirtyLo128 &= ~RT_BIT_64(a_iSimdReg); \ 1146 (a_pReNative)->Core.bmGstSimdRegShadowDirtyHi128 &= ~RT_BIT_64(a_iSimdReg); \ 1147 } while (0) 1148 1149 /** Returns whether the low 128-bits of the given guest SIMD register are dirty. */ 1150 # define IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_LO_U128(a_pReNative, a_iSimdReg) \ 1151 RT_BOOL((a_pReNative)->Core.bmGstSimdRegShadowDirtyLo128 & RT_BIT_64(a_iSimdReg)) 1152 /** Returns whether the high 128-bits of the given guest SIMD register are dirty. */ 1153 # define IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_HI_U128(a_pReNative, a_iSimdReg) \ 1154 RT_BOOL((a_pReNative)->Core.bmGstSimdRegShadowDirtyHi128 & RT_BIT_64(a_iSimdReg)) 1155 /** Returns whether the given guest SIMD register is dirty. */ 1156 # define IEMNATIVE_SIMD_REG_STATE_IS_DIRTY_U256(a_pReNative, a_iSimdReg) \ 1157 RT_BOOL(((a_pReNative)->Core.bmGstSimdRegShadowDirtyLo128 | (a_pReNative)->Core.bmGstSimdRegShadowDirtyHi128) & RT_BIT_64(a_iSimdReg)) 1158 1159 /** Set the low 128-bits of the given guest SIMD register to the dirty state. */ 1160 # define IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_LO_U128(a_pReNative, a_iSimdReg) \ 1161 ((a_pReNative)->Core.bmGstSimdRegShadowDirtyLo128 |= RT_BIT_64(a_iSimdReg)) 1162 /** Set the high 128-bits of the given guest SIMD register to the dirty state. */ 1163 # define IEMNATIVE_SIMD_REG_STATE_SET_DIRTY_HI_U128(a_pReNative, a_iSimdReg) \ 1164 ((a_pReNative)->Core.bmGstSimdRegShadowDirtyHi128 |= RT_BIT_64(a_iSimdReg)) 984 1165 #endif 985 1166 … … 1238 1419 DECLHIDDEN(void) iemNativeRegFreeVar(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg, bool fFlushShadows) RT_NOEXCEPT; 1239 1420 DECLHIDDEN(void) iemNativeRegFreeAndFlushMask(PIEMRECOMPILERSTATE pReNative, uint32_t fHstRegMask) RT_NOEXCEPT; 1240 DECL_HIDDEN_THROW(uint32_t) iemNativeRegFlushPendingWrites(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint64_t fGstShwExept = 0 );1421 DECL_HIDDEN_THROW(uint32_t) iemNativeRegFlushPendingWrites(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint64_t fGstShwExept = 0, bool fFlushShadows = true); 1241 1422 DECL_HIDDEN_THROW(uint32_t) iemNativeRegMoveAndFreeAndFlushAtCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t cArgs, 1242 1423 uint32_t fKeepVars = 0); … … 1264 1445 DECL_HIDDEN_THROW(uint32_t) iemNativeEmitThreadedCall(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1265 1446 PCIEMTHRDEDCALLENTRY pCallEntry); 1447 1448 #ifdef IEMNATIVE_WITH_SIMD_REG_ALLOCATOR 1449 DECL_HIDDEN_THROW(uint8_t) iemNativeSimdRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, bool fPreferVolatile = true); 1450 DECL_HIDDEN_THROW(uint8_t) iemNativeSimdRegAllocTmpEx(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask, 1451 bool fPreferVolatile = true); 1452 DECL_HIDDEN_THROW(uint8_t) iemNativeSimdRegAllocTmpForGuestSimdReg(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, IEMNATIVEGSTSIMDREG enmGstSimdReg, 1453 IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz, IEMNATIVEGSTREGUSE enmIntendedUse = kIemNativeGstRegUse_ReadOnly, 1454 bool fNoVolatileRegs = false); 1455 DECL_HIDDEN_THROW(uint32_t) iemNativeEmitLoadSimdRegWithGstShadowSimdReg(PIEMRECOMPILERSTATE pReNative, uint32_t off, 1456 uint8_t idxHstSimdReg, IEMNATIVEGSTSIMDREG enmGstSimdReg, 1457 IEMNATIVEGSTSIMDREGLDSTSZ enmLoadSz); 1458 #endif 1266 1459 1267 1460 extern DECL_HIDDEN_DATA(const char * const) g_apszIemNativeHstRegNames[];
Note:
See TracChangeset
for help on using the changeset viewer.