Changeset 101557 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Oct 23, 2023 2:39:59 PM (17 months ago)
- svn:sync-xref-src-repo-rev:
- 159634
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py
r101538 r101557 2889 2889 'IEM_MC_IF_EFL_BIT_NOT_SET': (McBlock.parseMcGenericCond, True, False, ), 2890 2890 'IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ': (McBlock.parseMcGenericCond, True, False, ), 2891 'IEM_MC_IF_EFL_BIT_SET': (McBlock.parseMcGenericCond, True, False, ), #True, ),2891 'IEM_MC_IF_EFL_BIT_SET': (McBlock.parseMcGenericCond, True, True, ), 2892 2892 'IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE': (McBlock.parseMcGenericCond, True, False, ), 2893 2893 'IEM_MC_IF_EFL_BITS_EQ': (McBlock.parseMcGenericCond, True, False, ), -
trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
r101548 r101557 15 15 * - Level 9 (Log9) : ... 16 16 * - Level 10 (Log10): ... 17 * - Level 11 (Log11): ...18 * - Level 12 (Log12): Register allocator 17 * - Level 11 (Log11): Variable allocator. 18 * - Level 12 (Log12): Register allocator. 19 19 */ 20 20 … … 1579 1579 static PIEMRECOMPILERSTATE iemNativeReInit(PIEMRECOMPILERSTATE pReNative, PCIEMTB pTb) 1580 1580 { 1581 pReNative->cLabels = 0;1582 pReNative->bmLabelTypes = 0;1583 pReNative->cFixups = 0;1581 pReNative->cLabels = 0; 1582 pReNative->bmLabelTypes = 0; 1583 pReNative->cFixups = 0; 1584 1584 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 1585 pReNative->pDbgInfo->cEntries = 0; 1586 #endif 1587 pReNative->pTbOrg = pTb; 1588 1589 pReNative->bmHstRegs = IEMNATIVE_REG_FIXED_MASK 1585 pReNative->pDbgInfo->cEntries = 0; 1586 #endif 1587 pReNative->pTbOrg = pTb; 1588 pReNative->cCondDepth = 0; 1589 pReNative->uCondSeqNo = 0; 1590 1591 pReNative->Core.bmHstRegs = IEMNATIVE_REG_FIXED_MASK 1590 1592 #if IEMNATIVE_HST_GREG_COUNT < 32 1591 | ~(RT_BIT(IEMNATIVE_HST_GREG_COUNT) - 1U) 1592 #endif 1593 ; 1594 pReNative->bmHstRegsWithGstShadow = 0; 1595 pReNative->bmGstRegShadows = 0; 1596 pReNative->cCondDepth = 0; 1597 pReNative->uCondSeqNo = 0; 1598 pReNative->bmVars = 0; 1599 pReNative->u64ArgVars = UINT64_MAX; 1593 | ~(RT_BIT(IEMNATIVE_HST_GREG_COUNT) - 1U) 1594 #endif 1595 ; 1596 pReNative->Core.bmHstRegsWithGstShadow = 0; 1597 pReNative->Core.bmGstRegShadows = 0; 1598 pReNative->Core.bmVars = 0; 1599 pReNative->Core.u64ArgVars = UINT64_MAX; 1600 1600 1601 1601 /* Full host register reinit: */ 1602 for (unsigned i = 0; i < RT_ELEMENTS(pReNative-> aHstRegs); i++)1603 { 1604 pReNative-> aHstRegs[i].fGstRegShadows = 0;1605 pReNative-> aHstRegs[i].enmWhat = kIemNativeWhat_Invalid;1606 pReNative-> aHstRegs[i].idxVar = UINT8_MAX;1602 for (unsigned i = 0; i < RT_ELEMENTS(pReNative->Core.aHstRegs); i++) 1603 { 1604 pReNative->Core.aHstRegs[i].fGstRegShadows = 0; 1605 pReNative->Core.aHstRegs[i].enmWhat = kIemNativeWhat_Invalid; 1606 pReNative->Core.aHstRegs[i].idxVar = UINT8_MAX; 1607 1607 } 1608 1608 … … 1619 1619 { 1620 1620 fRegs &= ~RT_BIT_32(idxReg); 1621 pReNative-> aHstRegs[IEMNATIVE_REG_FIXED_PVMCPU].enmWhat = kIemNativeWhat_FixedReserved;1622 } 1623 1624 pReNative-> aHstRegs[IEMNATIVE_REG_FIXED_PVMCPU].enmWhat = kIemNativeWhat_pVCpuFixed;1621 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_PVMCPU].enmWhat = kIemNativeWhat_FixedReserved; 1622 } 1623 1624 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_PVMCPU].enmWhat = kIemNativeWhat_pVCpuFixed; 1625 1625 #ifdef IEMNATIVE_REG_FIXED_PCPUMCTX 1626 pReNative-> aHstRegs[IEMNATIVE_REG_FIXED_PCPUMCTX].enmWhat = kIemNativeWhat_pCtxFixed;1626 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_PCPUMCTX].enmWhat = kIemNativeWhat_pCtxFixed; 1627 1627 #endif 1628 1628 #ifdef IEMNATIVE_REG_FIXED_TMP0 1629 pReNative-> aHstRegs[IEMNATIVE_REG_FIXED_TMP0].enmWhat = kIemNativeWhat_FixedTmp;1629 pReNative->Core.aHstRegs[IEMNATIVE_REG_FIXED_TMP0].enmWhat = kIemNativeWhat_FixedTmp; 1630 1630 #endif 1631 1631 return pReNative; … … 2181 2181 IEMNATIVEWHAT enmWhat, uint8_t idxVar = UINT8_MAX) RT_NOEXCEPT 2182 2182 { 2183 pReNative-> bmHstRegs |= RT_BIT_32(idxReg);2184 2185 pReNative-> aHstRegs[idxReg].enmWhat = enmWhat;2186 pReNative-> aHstRegs[idxReg].fGstRegShadows = 0;2187 pReNative-> aHstRegs[idxReg].idxVar = idxVar;2183 pReNative->Core.bmHstRegs |= RT_BIT_32(idxReg); 2184 2185 pReNative->Core.aHstRegs[idxReg].enmWhat = enmWhat; 2186 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0; 2187 pReNative->Core.aHstRegs[idxReg].idxVar = idxVar; 2188 2188 return (uint8_t)idxReg; 2189 2189 } … … 2205 2205 * Try a freed register that's shadowing a guest register 2206 2206 */ 2207 uint32_t fRegs = ~pReNative-> bmHstRegs & fRegMask;2207 uint32_t fRegs = ~pReNative->Core.bmHstRegs & fRegMask; 2208 2208 if (fRegs) 2209 2209 { … … 2211 2211 unsigned const idxReg = ASMBitFirstSetU32(fRegs) - 1; 2212 2212 2213 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows != 0);2214 Assert( (pReNative-> aHstRegs[idxReg].fGstRegShadows & pReNative->bmGstRegShadows)2215 == pReNative-> aHstRegs[idxReg].fGstRegShadows);2216 Assert(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg));2217 2218 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxReg].fGstRegShadows;2219 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);2220 pReNative-> aHstRegs[idxReg].fGstRegShadows = 0;2213 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows != 0); 2214 Assert( (pReNative->Core.aHstRegs[idxReg].fGstRegShadows & pReNative->Core.bmGstRegShadows) 2215 == pReNative->Core.aHstRegs[idxReg].fGstRegShadows); 2216 Assert(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)); 2217 2218 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 2219 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg); 2220 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0; 2221 2221 return idxReg; 2222 2222 } … … 2230 2230 for (uint32_t iLoop = 0; iLoop < 2; iLoop++) 2231 2231 { 2232 uint32_t fVars = pReNative-> bmVars;2232 uint32_t fVars = pReNative->Core.bmVars; 2233 2233 while (fVars) 2234 2234 { 2235 2235 uint32_t const idxVar = ASMBitFirstSetU32(fVars) - 1; 2236 uint8_t const idxReg = pReNative-> aVars[idxVar].idxReg;2237 if ( idxReg < RT_ELEMENTS(pReNative-> aHstRegs)2236 uint8_t const idxReg = pReNative->Core.aVars[idxVar].idxReg; 2237 if ( idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs) 2238 2238 && (RT_BIT_32(idxReg) & fRegMask) 2239 2239 && ( iLoop == 0 2240 ? pReNative-> aVars[idxVar].enmKind != kIemNativeVarKind_Stack2241 : pReNative-> aVars[idxVar].enmKind == kIemNativeVarKind_Stack))2240 ? pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack 2241 : pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack)) 2242 2242 { 2243 Assert(pReNative-> bmHstRegs & RT_BIT_32(idxReg));2244 Assert( (pReNative-> bmGstRegShadows & pReNative->aHstRegs[idxReg].fGstRegShadows)2245 == pReNative-> aHstRegs[idxReg].fGstRegShadows);2246 Assert( RT_BOOL(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg))2247 == RT_BOOL(pReNative-> aHstRegs[idxReg].fGstRegShadows));2248 2249 if (pReNative-> aVars[idxVar].enmKind == kIemNativeVarKind_Stack)2243 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)); 2244 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxReg].fGstRegShadows) 2245 == pReNative->Core.aHstRegs[idxReg].fGstRegShadows); 2246 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)) 2247 == RT_BOOL(pReNative->Core.aHstRegs[idxReg].fGstRegShadows)); 2248 2249 if (pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack) 2250 2250 { 2251 AssertReturn(pReNative-> aVars[idxVar].idxStackSlot != UINT8_MAX, UINT8_MAX);2251 AssertReturn(pReNative->Core.aVars[idxVar].idxStackSlot != UINT8_MAX, UINT8_MAX); 2252 2252 uint32_t off = *poff; 2253 2253 *poff = off = iemNativeEmitStoreGprByBp(pReNative, off, 2254 pReNative-> aVars[idxVar].idxStackSlot * sizeof(uint64_t)2254 pReNative->Core.aVars[idxVar].idxStackSlot * sizeof(uint64_t) 2255 2255 - IEMNATIVE_FP_OFF_STACK_VARS, 2256 2256 idxReg); … … 2258 2258 } 2259 2259 2260 pReNative-> aVars[idxVar].idxReg = UINT8_MAX;2261 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxReg].fGstRegShadows;2262 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg);2263 pReNative-> bmHstRegs &= ~RT_BIT_32(idxReg);2260 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 2261 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 2262 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxReg); 2263 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxReg); 2264 2264 return idxReg; 2265 2265 } … … 2288 2288 uint32_t fForbiddenRegs = IEMNATIVE_CALL_VOLATILE_GREG_MASK) 2289 2289 { 2290 Assert(idxVar < RT_ELEMENTS(pReNative-> aVars));2291 Assert(pReNative-> aVars[idxVar].enmKind == kIemNativeVarKind_Stack);2292 2293 uint8_t const idxRegOld = pReNative-> aVars[idxVar].idxReg;2294 Assert(idxRegOld < RT_ELEMENTS(pReNative-> aHstRegs));2295 Assert(pReNative-> bmHstRegs & RT_BIT_32(idxRegOld));2296 Assert(pReNative-> aHstRegs[idxRegOld].enmWhat == kIemNativeWhat_Var);2297 Assert( (pReNative-> bmGstRegShadows & pReNative->aHstRegs[idxRegOld].fGstRegShadows)2298 == pReNative-> aHstRegs[idxRegOld].fGstRegShadows);2299 Assert( RT_BOOL(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxRegOld))2300 == RT_BOOL(pReNative-> aHstRegs[idxRegOld].fGstRegShadows));2290 Assert(idxVar < RT_ELEMENTS(pReNative->Core.aVars)); 2291 Assert(pReNative->Core.aVars[idxVar].enmKind == kIemNativeVarKind_Stack); 2292 2293 uint8_t const idxRegOld = pReNative->Core.aVars[idxVar].idxReg; 2294 Assert(idxRegOld < RT_ELEMENTS(pReNative->Core.aHstRegs)); 2295 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxRegOld)); 2296 Assert(pReNative->Core.aHstRegs[idxRegOld].enmWhat == kIemNativeWhat_Var); 2297 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows) 2298 == pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows); 2299 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxRegOld)) 2300 == RT_BOOL(pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows)); 2301 2301 2302 2302 … … 2311 2311 fForbiddenRegs |= RT_BIT_32(idxRegOld); 2312 2312 fForbiddenRegs |= IEMNATIVE_REG_FIXED_MASK; 2313 uint32_t fRegs = ~pReNative-> bmHstRegs & ~fForbiddenRegs;2313 uint32_t fRegs = ~pReNative->Core.bmHstRegs & ~fForbiddenRegs; 2314 2314 if (fRegs) 2315 2315 { 2316 2316 /* Avoid using shadow registers, if possible. */ 2317 if (fRegs & ~pReNative-> bmHstRegsWithGstShadow)2318 fRegs &= ~pReNative-> bmHstRegsWithGstShadow;2317 if (fRegs & ~pReNative->Core.bmHstRegsWithGstShadow) 2318 fRegs &= ~pReNative->Core.bmHstRegsWithGstShadow; 2319 2319 unsigned const idxRegNew = ASMBitFirstSetU32(fRegs) - 1; 2320 2320 2321 uint64_t fGstRegShadows = pReNative-> aHstRegs[idxRegOld].fGstRegShadows;2322 pReNative-> aHstRegs[idxRegNew].fGstRegShadows = fGstRegShadows;2323 pReNative-> aHstRegs[idxRegNew].enmWhat = kIemNativeWhat_Var;2324 pReNative-> aHstRegs[idxRegNew].idxVar = idxVar;2321 uint64_t fGstRegShadows = pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows; 2322 pReNative->Core.aHstRegs[idxRegNew].fGstRegShadows = fGstRegShadows; 2323 pReNative->Core.aHstRegs[idxRegNew].enmWhat = kIemNativeWhat_Var; 2324 pReNative->Core.aHstRegs[idxRegNew].idxVar = idxVar; 2325 2325 if (fGstRegShadows) 2326 2326 { 2327 pReNative-> bmHstRegsWithGstShadow |= RT_BIT_32(idxRegNew);2327 pReNative->Core.bmHstRegsWithGstShadow |= RT_BIT_32(idxRegNew); 2328 2328 while (fGstRegShadows) 2329 2329 { … … 2331 2331 fGstRegShadows &= ~RT_BIT_64(idxGstReg); 2332 2332 2333 Assert(pReNative-> aidxGstRegShadows[idxGstReg] == idxRegOld);2334 pReNative-> aidxGstRegShadows[idxGstReg] = idxRegNew;2333 Assert(pReNative->Core.aidxGstRegShadows[idxGstReg] == idxRegOld); 2334 pReNative->Core.aidxGstRegShadows[idxGstReg] = idxRegNew; 2335 2335 } 2336 2336 } 2337 2337 2338 pReNative-> aVars[idxVar].idxReg = (uint8_t)idxRegNew;2339 pReNative-> bmHstRegs |= RT_BIT_32(idxRegNew);2338 pReNative->Core.aVars[idxVar].idxReg = (uint8_t)idxRegNew; 2339 pReNative->Core.bmHstRegs |= RT_BIT_32(idxRegNew); 2340 2340 } 2341 2341 /* … … 2344 2344 else 2345 2345 { 2346 AssertReturn(pReNative-> aVars[idxVar].idxStackSlot != UINT8_MAX, UINT32_MAX);2346 AssertReturn(pReNative->Core.aVars[idxVar].idxStackSlot != UINT8_MAX, UINT32_MAX); 2347 2347 off = iemNativeEmitStoreGprByBp(pReNative, off, 2348 pReNative->aVars[idxVar].idxStackSlot * sizeof(uint64_t) - IEMNATIVE_FP_OFF_STACK_VARS, 2348 pReNative->Core.aVars[idxVar].idxStackSlot * sizeof(uint64_t) 2349 - IEMNATIVE_FP_OFF_STACK_VARS, 2349 2350 idxRegOld); 2350 2351 AssertReturn(off != UINT32_MAX, UINT32_MAX); 2351 2352 2352 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxRegOld);2353 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxRegOld].fGstRegShadows;2354 } 2355 2356 pReNative-> bmHstRegs &= ~RT_BIT_32(idxRegOld);2357 pReNative-> aHstRegs[idxRegOld].fGstRegShadows = 0;2353 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxRegOld); 2354 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows; 2355 } 2356 2357 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxRegOld); 2358 pReNative->Core.aHstRegs[idxRegOld].fGstRegShadows = 0; 2358 2359 return off; 2359 2360 } … … 2382 2383 */ 2383 2384 uint8_t idxReg; 2384 uint32_t fRegs = ~pReNative-> bmHstRegs2385 & ~pReNative-> bmHstRegsWithGstShadow2385 uint32_t fRegs = ~pReNative->Core.bmHstRegs 2386 & ~pReNative->Core.bmHstRegsWithGstShadow 2386 2387 & (~IEMNATIVE_REG_FIXED_MASK & IEMNATIVE_HST_GREG_MASK); 2387 2388 if (fRegs) … … 2393 2394 idxReg = (uint8_t)ASMBitFirstSetU32( fRegs & ~IEMNATIVE_CALL_VOLATILE_GREG_MASK 2394 2395 ? fRegs & ~IEMNATIVE_CALL_VOLATILE_GREG_MASK : fRegs) - 1; 2395 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows == 0);2396 Assert(!(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg)));2396 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows == 0); 2397 Assert(!(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg))); 2397 2398 } 2398 2399 else … … 2429 2430 { 2430 2431 uint8_t idxReg = iemNativeRegAllocTmp(pReNative, poff, fPreferVolatile); 2431 if (idxReg < RT_ELEMENTS(pReNative-> aHstRegs))2432 if (idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs)) 2432 2433 { 2433 2434 uint32_t off = *poff; … … 2449 2450 iemNativeRegMarkAsGstRegShadow(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg, IEMNATIVEGSTREG enmGstReg, uint32_t off) 2450 2451 { 2451 Assert(!(pReNative-> bmGstRegShadows & RT_BIT_64(enmGstReg)));2452 2453 pReNative-> aidxGstRegShadows[enmGstReg] = idxHstReg;2454 pReNative-> aHstRegs[idxHstReg].fGstRegShadows = RT_BIT_64(enmGstReg);2455 pReNative-> bmGstRegShadows |= RT_BIT_64(enmGstReg);2456 pReNative-> bmHstRegsWithGstShadow |= RT_BIT_32(idxHstReg);2452 Assert(!(pReNative->Core.bmGstRegShadows & RT_BIT_64(enmGstReg))); 2453 2454 pReNative->Core.aidxGstRegShadows[enmGstReg] = idxHstReg; 2455 pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = RT_BIT_64(enmGstReg); 2456 pReNative->Core.bmGstRegShadows |= RT_BIT_64(enmGstReg); 2457 pReNative->Core.bmHstRegsWithGstShadow |= RT_BIT_32(idxHstReg); 2457 2458 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 2458 2459 iemNativeDbgInfoAddNativeOffset(pReNative, off); … … 2472 2473 iemNativeRegClearGstRegShadowing(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg, uint32_t off) 2473 2474 { 2474 Assert( (pReNative-> bmGstRegShadows & pReNative->aHstRegs[idxHstReg].fGstRegShadows)2475 == pReNative-> aHstRegs[idxHstReg].fGstRegShadows);2476 Assert( RT_BOOL(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg))2477 == RT_BOOL(pReNative-> aHstRegs[idxHstReg].fGstRegShadows));2475 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows) 2476 == pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows); 2477 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg)) 2478 == RT_BOOL(pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows)); 2478 2479 2479 2480 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 2480 uint64_t fGstRegs = pReNative-> aHstRegs[idxHstReg].fGstRegShadows;2481 uint64_t fGstRegs = pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows; 2481 2482 if (fGstRegs) 2482 2483 { … … 2493 2494 #endif 2494 2495 2495 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg);2496 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxHstReg].fGstRegShadows;2497 pReNative-> aHstRegs[idxHstReg].fGstRegShadows = 0;2496 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg); 2497 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows; 2498 pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = 0; 2498 2499 } 2499 2500 … … 2507 2508 IEMNATIVEGSTREG enmGstReg, uint32_t off) 2508 2509 { 2509 Assert(pReNative-> aHstRegs[idxRegFrom].fGstRegShadows & RT_BIT_64(enmGstReg));2510 Assert( (pReNative-> bmGstRegShadows & pReNative->aHstRegs[idxRegFrom].fGstRegShadows)2511 == pReNative-> aHstRegs[idxRegFrom].fGstRegShadows);2512 Assert( RT_BOOL(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxRegFrom))2513 == RT_BOOL(pReNative-> aHstRegs[idxRegFrom].fGstRegShadows));2514 2515 pReNative-> aHstRegs[idxRegFrom].fGstRegShadows &= ~RT_BIT_64(enmGstReg);2516 pReNative-> aHstRegs[idxRegTo].fGstRegShadows = RT_BIT_64(enmGstReg);2517 pReNative-> aidxGstRegShadows[enmGstReg] = idxRegTo;2510 Assert(pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows & RT_BIT_64(enmGstReg)); 2511 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows) 2512 == pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows); 2513 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxRegFrom)) 2514 == RT_BOOL(pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows)); 2515 2516 pReNative->Core.aHstRegs[idxRegFrom].fGstRegShadows &= ~RT_BIT_64(enmGstReg); 2517 pReNative->Core.aHstRegs[idxRegTo].fGstRegShadows = RT_BIT_64(enmGstReg); 2518 pReNative->Core.aidxGstRegShadows[enmGstReg] = idxRegTo; 2518 2519 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 2519 2520 iemNativeDbgInfoAddNativeOffset(pReNative, off); … … 2572 2573 * First check if the guest register value is already in a host register. 2573 2574 */ 2574 if (pReNative-> bmGstRegShadows & RT_BIT_64(enmGstReg))2575 { 2576 uint8_t idxReg = pReNative-> aidxGstRegShadows[enmGstReg];2577 Assert(idxReg < RT_ELEMENTS(pReNative-> aHstRegs));2578 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows & RT_BIT_64(enmGstReg));2579 Assert(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg));2580 2581 if (!(pReNative-> bmHstRegs & RT_BIT_32(idxReg)))2575 if (pReNative->Core.bmGstRegShadows & RT_BIT_64(enmGstReg)) 2576 { 2577 uint8_t idxReg = pReNative->Core.aidxGstRegShadows[enmGstReg]; 2578 Assert(idxReg < RT_ELEMENTS(pReNative->Core.aHstRegs)); 2579 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows & RT_BIT_64(enmGstReg)); 2580 Assert(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)); 2581 2582 if (!(pReNative->Core.bmHstRegs & RT_BIT_32(idxReg))) 2582 2583 { 2583 2584 /* … … 2588 2589 /** @todo would be nice to know if preserving the register is in any way helpful. */ 2589 2590 if ( enmIntendedUse == kIemNativeGstRegUse_Calculation 2590 && ( ~pReNative-> bmHstRegs2591 & ~pReNative-> bmHstRegsWithGstShadow2591 && ( ~pReNative->Core.bmHstRegs 2592 & ~pReNative->Core.bmHstRegsWithGstShadow 2592 2593 & (~IEMNATIVE_REG_FIXED_MASK & IEMNATIVE_HST_GREG_MASK))) 2593 2594 { 2594 2595 uint8_t const idxRegNew = iemNativeRegAllocTmp(pReNative, poff); 2595 Assert(idxRegNew < RT_ELEMENTS(pReNative-> aHstRegs));2596 Assert(idxRegNew < RT_ELEMENTS(pReNative->Core.aHstRegs)); 2596 2597 2597 2598 uint32_t off = *poff; … … 2606 2607 else 2607 2608 { 2608 pReNative-> bmHstRegs |= RT_BIT_32(idxReg);2609 pReNative-> aHstRegs[idxReg].enmWhat = kIemNativeWhat_Tmp;2610 pReNative-> aHstRegs[idxReg].idxVar = UINT8_MAX;2609 pReNative->Core.bmHstRegs |= RT_BIT_32(idxReg); 2610 pReNative->Core.aHstRegs[idxReg].enmWhat = kIemNativeWhat_Tmp; 2611 pReNative->Core.aHstRegs[idxReg].idxVar = UINT8_MAX; 2611 2612 if (enmIntendedUse != kIemNativeGstRegUse_Calculation) 2612 2613 Log12(("iemNativeRegAllocTmpForGuestReg: Reusing %s for guest %s %s\n", … … 2631 2632 /** @todo share register for readonly access. */ 2632 2633 uint8_t const idxRegNew = iemNativeRegAllocTmp(pReNative, poff, enmIntendedUse == kIemNativeGstRegUse_Calculation); 2633 AssertReturn(idxRegNew < RT_ELEMENTS(pReNative-> aHstRegs), UINT8_MAX);2634 AssertReturn(idxRegNew < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT8_MAX); 2634 2635 2635 2636 uint32_t off = *poff; … … 2665 2666 */ 2666 2667 uint8_t const idxRegNew = iemNativeRegAllocTmp(pReNative, poff, enmIntendedUse == kIemNativeGstRegUse_Calculation); 2667 AssertReturn(idxRegNew < RT_ELEMENTS(pReNative-> aHstRegs), UINT8_MAX);2668 AssertReturn(idxRegNew < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT8_MAX); 2668 2669 2669 2670 uint32_t off = *poff; … … 2705 2706 * Do we get luck and all register are free and not shadowing anything? 2706 2707 */ 2707 if (((pReNative-> bmHstRegs | pReNative->bmHstRegsWithGstShadow) & g_afIemNativeCallRegs[cArgs]) == 0)2708 if (((pReNative->Core.bmHstRegs | pReNative->Core.bmHstRegsWithGstShadow) & g_afIemNativeCallRegs[cArgs]) == 0) 2708 2709 for (uint32_t i = 0; i < cArgs; i++) 2709 2710 { 2710 2711 uint8_t const idxReg = g_aidxIemNativeCallRegs[i]; 2711 pReNative-> aHstRegs[idxReg].enmWhat = kIemNativeWhat_Arg;2712 pReNative-> aHstRegs[idxReg].idxVar = UINT8_MAX;2713 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows == 0);2712 pReNative->Core.aHstRegs[idxReg].enmWhat = kIemNativeWhat_Arg; 2713 pReNative->Core.aHstRegs[idxReg].idxVar = UINT8_MAX; 2714 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows == 0); 2714 2715 } 2715 2716 /* … … 2720 2721 { 2721 2722 uint8_t const idxReg = g_aidxIemNativeCallRegs[i]; 2722 if (pReNative-> bmHstRegs & RT_BIT_32(idxReg))2723 if (pReNative->Core.bmHstRegs & RT_BIT_32(idxReg)) 2723 2724 { 2724 switch (pReNative-> aHstRegs[idxReg].enmWhat)2725 switch (pReNative->Core.aHstRegs[idxReg].enmWhat) 2725 2726 { 2726 2727 case kIemNativeWhat_Var: 2727 2728 { 2728 uint8_t const idxVar = pReNative-> aHstRegs[idxReg].idxVar;2729 AssertReturn(idxVar < RT_ELEMENTS(pReNative-> aVars), false);2730 Assert(pReNative-> aVars[idxVar].idxReg == idxReg);2731 Assert(pReNative-> bmVars & RT_BIT_32(idxVar));2732 2733 if (pReNative-> aVars[idxVar].enmKind != kIemNativeVarKind_Stack)2734 pReNative-> aVars[idxVar].idxReg = UINT8_MAX;2729 uint8_t const idxVar = pReNative->Core.aHstRegs[idxReg].idxVar; 2730 AssertReturn(idxVar < RT_ELEMENTS(pReNative->Core.aVars), false); 2731 Assert(pReNative->Core.aVars[idxVar].idxReg == idxReg); 2732 Assert(pReNative->Core.bmVars & RT_BIT_32(idxVar)); 2733 2734 if (pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack) 2735 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 2735 2736 else 2736 2737 { 2737 2738 off = iemNativeRegMoveOrSpillStackVar(pReNative, off, idxVar); 2738 2739 AssertReturn(off != UINT32_MAX, false); 2739 Assert(!(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg)));2740 Assert(!(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg))); 2740 2741 } 2741 2742 break; … … 2751 2752 2752 2753 } 2753 if (pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxReg))2754 if (pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)) 2754 2755 { 2755 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows != 0);2756 Assert( (pReNative-> aHstRegs[idxReg].fGstRegShadows & pReNative->bmGstRegShadows)2757 == pReNative-> aHstRegs[idxReg].fGstRegShadows);2758 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxReg].fGstRegShadows;2759 pReNative-> aHstRegs[idxReg].fGstRegShadows = 0;2756 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows != 0); 2757 Assert( (pReNative->Core.aHstRegs[idxReg].fGstRegShadows & pReNative->Core.bmGstRegShadows) 2758 == pReNative->Core.aHstRegs[idxReg].fGstRegShadows); 2759 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 2760 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0; 2760 2761 } 2761 2762 else 2762 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows == 0);2763 pReNative-> aHstRegs[idxReg].enmWhat = kIemNativeWhat_Arg;2764 pReNative-> aHstRegs[idxReg].idxVar = UINT8_MAX;2763 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows == 0); 2764 pReNative->Core.aHstRegs[idxReg].enmWhat = kIemNativeWhat_Arg; 2765 pReNative->Core.aHstRegs[idxReg].idxVar = UINT8_MAX; 2765 2766 } 2766 pReNative-> bmHstRegs |= g_afIemNativeCallRegs[cArgs];2767 pReNative->Core.bmHstRegs |= g_afIemNativeCallRegs[cArgs]; 2767 2768 return true; 2768 2769 } … … 2783 2784 DECLHIDDEN(void) iemNativeRegFree(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT 2784 2785 { 2785 Assert(idxHstReg < RT_ELEMENTS(pReNative-> aHstRegs));2786 Assert(pReNative-> bmHstRegs & RT_BIT_32(idxHstReg));2786 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aHstRegs)); 2787 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxHstReg)); 2787 2788 Assert(!(IEMNATIVE_REG_FIXED_MASK & RT_BIT_32(idxHstReg))); 2788 Assert( pReNative-> aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Var2789 || pReNative-> aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Tmp2790 || pReNative-> aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Arg2791 || pReNative-> aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_rc);2792 Assert( pReNative-> aHstRegs[idxHstReg].enmWhat != kIemNativeWhat_Var2793 || pReNative-> aVars[pReNative->aHstRegs[idxHstReg].idxVar].idxReg == UINT8_MAX2794 || (pReNative-> bmVars & RT_BIT_32(pReNative->aHstRegs[idxHstReg].idxVar)));2795 Assert( (pReNative-> bmGstRegShadows & pReNative->aHstRegs[idxHstReg].fGstRegShadows)2796 == pReNative-> aHstRegs[idxHstReg].fGstRegShadows);2797 Assert( RT_BOOL(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg))2798 == RT_BOOL(pReNative-> aHstRegs[idxHstReg].fGstRegShadows));2799 2800 pReNative-> bmHstRegs &= ~RT_BIT_32(idxHstReg);2789 Assert( pReNative->Core.aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Var 2790 || pReNative->Core.aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Tmp 2791 || pReNative->Core.aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Arg 2792 || pReNative->Core.aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_rc); 2793 Assert( pReNative->Core.aHstRegs[idxHstReg].enmWhat != kIemNativeWhat_Var 2794 || pReNative->Core.aVars[pReNative->Core.aHstRegs[idxHstReg].idxVar].idxReg == UINT8_MAX 2795 || (pReNative->Core.bmVars & RT_BIT_32(pReNative->Core.aHstRegs[idxHstReg].idxVar))); 2796 Assert( (pReNative->Core.bmGstRegShadows & pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows) 2797 == pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows); 2798 Assert( RT_BOOL(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg)) 2799 == RT_BOOL(pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows)); 2800 2801 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg); 2801 2802 /* no flushing, right: 2802 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg);2803 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxHstReg].fGstRegShadows;2804 pReNative-> aHstRegs[idxHstReg].fGstRegShadows = 0;2803 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg); 2804 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows; 2805 pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = 0; 2805 2806 */ 2806 2807 } … … 2816 2817 DECLHIDDEN(void) iemNativeRegFreeTmp(PIEMRECOMPILERSTATE pReNative, uint8_t idxHstReg) RT_NOEXCEPT 2817 2818 { 2818 Assert(pReNative-> bmHstRegs & RT_BIT_32(idxHstReg));2819 Assert(pReNative-> aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Tmp);2820 pReNative-> bmHstRegs &= ~RT_BIT_32(idxHstReg);2819 Assert(pReNative->Core.bmHstRegs & RT_BIT_32(idxHstReg)); 2820 Assert(pReNative->Core.aHstRegs[idxHstReg].enmWhat == kIemNativeWhat_Tmp); 2821 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg); 2821 2822 Log12(("iemNativeRegFreeTmp: %s (gst: %#RX64)\n", 2822 g_apszIemNativeHstRegNames[idxHstReg], pReNative-> aHstRegs[idxHstReg].fGstRegShadows));2823 g_apszIemNativeHstRegNames[idxHstReg], pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows)); 2823 2824 } 2824 2825 … … 2856 2857 * Free argument variables first (simplified). 2857 2858 */ 2858 AssertReturn(cArgs <= RT_ELEMENTS(pReNative-> aidxArgVars), UINT32_MAX);2859 AssertReturn(cArgs <= RT_ELEMENTS(pReNative->Core.aidxArgVars), UINT32_MAX); 2859 2860 if (fFreeArgVars && cArgs > 0) 2860 2861 { 2861 2862 for (uint32_t i = 0; i < cArgs; i++) 2862 2863 { 2863 uint8_t idxVar = pReNative-> aidxArgVars[i];2864 if (idxVar < RT_ELEMENTS(pReNative-> aVars))2864 uint8_t idxVar = pReNative->Core.aidxArgVars[i]; 2865 if (idxVar < RT_ELEMENTS(pReNative->Core.aVars)) 2865 2866 { 2866 pReNative-> aidxArgVars[i] = UINT8_MAX;2867 pReNative-> bmVars &= ~RT_BIT_32(idxVar);2868 Assert( pReNative-> aVars[idxVar].idxReg2867 pReNative->Core.aidxArgVars[i] = UINT8_MAX; 2868 pReNative->Core.bmVars &= ~RT_BIT_32(idxVar); 2869 Assert( pReNative->Core.aVars[idxVar].idxReg 2869 2870 == (i < RT_ELEMENTS(g_aidxIemNativeCallRegs) ? g_aidxIemNativeCallRegs[i] : UINT8_MAX)); 2870 2871 } 2871 2872 } 2872 Assert(pReNative-> u64ArgVars == UINT64_MAX);2873 Assert(pReNative->Core.u64ArgVars == UINT64_MAX); 2873 2874 } 2874 2875 … … 2884 2885 & ~g_afIemNativeCallRegs[cArgs]; 2885 2886 2886 fRegsToMove &= pReNative-> bmHstRegs;2887 fRegsToMove &= pReNative->Core.bmHstRegs; 2887 2888 if (!fRegsToMove) 2888 2889 { /* likely */ } … … 2893 2894 fRegsToMove &= ~RT_BIT_32(idxReg); 2894 2895 2895 switch (pReNative-> aHstRegs[idxReg].enmWhat)2896 switch (pReNative->Core.aHstRegs[idxReg].enmWhat) 2896 2897 { 2897 2898 case kIemNativeWhat_Var: 2898 2899 { 2899 uint8_t const idxVar = pReNative-> aHstRegs[idxReg].idxVar;2900 Assert(idxVar < RT_ELEMENTS(pReNative-> aVars));2901 Assert(pReNative-> bmVars & RT_BIT_32(idxVar));2902 Assert(pReNative-> aVars[idxVar].idxReg == idxReg);2903 if (pReNative-> aVars[idxVar].enmKind != kIemNativeVarKind_Stack)2904 pReNative-> aVars[idxVar].idxReg = UINT8_MAX;2900 uint8_t const idxVar = pReNative->Core.aHstRegs[idxReg].idxVar; 2901 Assert(idxVar < RT_ELEMENTS(pReNative->Core.aVars)); 2902 Assert(pReNative->Core.bmVars & RT_BIT_32(idxVar)); 2903 Assert(pReNative->Core.aVars[idxVar].idxReg == idxReg); 2904 if (pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack) 2905 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 2905 2906 else 2906 2907 { … … 2934 2935 * Do the actual freeing. 2935 2936 */ 2936 pReNative-> bmHstRegs &= ~IEMNATIVE_CALL_VOLATILE_GREG_MASK;2937 pReNative->Core.bmHstRegs &= ~IEMNATIVE_CALL_VOLATILE_GREG_MASK; 2937 2938 2938 2939 /* If there are guest register shadows in any call-volatile register, we 2939 2940 have to clear the corrsponding guest register masks for each register. */ 2940 uint32_t fHstRegsWithGstShadow = pReNative-> bmHstRegsWithGstShadow & IEMNATIVE_CALL_VOLATILE_GREG_MASK;2941 uint32_t fHstRegsWithGstShadow = pReNative->Core.bmHstRegsWithGstShadow & IEMNATIVE_CALL_VOLATILE_GREG_MASK; 2941 2942 if (fHstRegsWithGstShadow) 2942 2943 { 2943 pReNative-> bmHstRegsWithGstShadow &= ~fHstRegsWithGstShadow;2944 pReNative->Core.bmHstRegsWithGstShadow &= ~fHstRegsWithGstShadow; 2944 2945 do 2945 2946 { … … 2947 2948 fHstRegsWithGstShadow = ~RT_BIT_32(idxReg); 2948 2949 2949 Assert(pReNative-> aHstRegs[idxReg].fGstRegShadows != 0);2950 pReNative-> bmGstRegShadows &= ~pReNative->aHstRegs[idxReg].fGstRegShadows;2951 pReNative-> aHstRegs[idxReg].fGstRegShadows = 0;2950 Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows != 0); 2951 pReNative->Core.bmGstRegShadows &= ~pReNative->Core.aHstRegs[idxReg].fGstRegShadows; 2952 pReNative->Core.aHstRegs[idxReg].fGstRegShadows = 0; 2952 2953 } while (fHstRegsWithGstShadow != 0); 2953 2954 } … … 2971 2972 * Reduce the mask by what's currently shadowed 2972 2973 */ 2973 fGstRegs &= pReNative-> bmGstRegShadows;2974 fGstRegs &= pReNative->Core.bmGstRegShadows; 2974 2975 if (fGstRegs) 2975 2976 { 2976 pReNative-> bmGstRegShadows &= ~fGstRegs;2977 if (pReNative-> bmGstRegShadows)2977 pReNative->Core.bmGstRegShadows &= ~fGstRegs; 2978 if (pReNative->Core.bmGstRegShadows) 2978 2979 { 2979 2980 /* … … 2983 2984 { 2984 2985 unsigned const idxGstReg = ASMBitFirstSetU64(fGstRegs) - 1; 2985 uint8_t const idxHstReg = pReNative-> aidxGstRegShadows[idxGstReg];2986 Assert(idxHstReg < RT_ELEMENTS(pReNative-> aidxGstRegShadows));2987 Assert(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg));2988 Assert(pReNative-> aHstRegs[idxHstReg].fGstRegShadows & RT_BIT_64(idxGstReg));2989 2990 uint64_t const fInThisHstReg = (pReNative-> aHstRegs[idxHstReg].fGstRegShadows & fGstRegs) | RT_BIT_64(idxGstReg);2986 uint8_t const idxHstReg = pReNative->Core.aidxGstRegShadows[idxGstReg]; 2987 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aidxGstRegShadows)); 2988 Assert(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg)); 2989 Assert(pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows & RT_BIT_64(idxGstReg)); 2990 2991 uint64_t const fInThisHstReg = (pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows & fGstRegs) | RT_BIT_64(idxGstReg); 2991 2992 fGstRegs &= ~fInThisHstReg; 2992 pReNative-> aHstRegs[idxHstReg].fGstRegShadows &= fInThisHstReg;2993 if (!pReNative-> aHstRegs[idxHstReg].fGstRegShadows)2994 pReNative-> bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg);2993 pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows &= fInThisHstReg; 2994 if (!pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows) 2995 pReNative->Core.bmHstRegsWithGstShadow &= ~RT_BIT_32(idxHstReg); 2995 2996 } while (fGstRegs != 0); 2996 2997 } … … 3003 3004 { 3004 3005 unsigned const idxGstReg = ASMBitFirstSetU64(fGstRegs) - 1; 3005 uint8_t const idxHstReg = pReNative-> aidxGstRegShadows[idxGstReg];3006 Assert(idxHstReg < RT_ELEMENTS(pReNative-> aidxGstRegShadows));3007 Assert(pReNative-> bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg));3008 Assert(pReNative-> aHstRegs[idxHstReg].fGstRegShadows & RT_BIT_64(idxGstReg));3009 3010 fGstRegs &= ~(pReNative-> aHstRegs[idxHstReg].fGstRegShadows | RT_BIT_64(idxGstReg));3011 pReNative-> aHstRegs[idxHstReg].fGstRegShadows = 0;3006 uint8_t const idxHstReg = pReNative->Core.aidxGstRegShadows[idxGstReg]; 3007 Assert(idxHstReg < RT_ELEMENTS(pReNative->Core.aidxGstRegShadows)); 3008 Assert(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxHstReg)); 3009 Assert(pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows & RT_BIT_64(idxGstReg)); 3010 3011 fGstRegs &= ~(pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows | RT_BIT_64(idxGstReg)); 3012 pReNative->Core.aHstRegs[idxHstReg].fGstRegShadows = 0; 3012 3013 } while (fGstRegs != 0); 3013 pReNative-> bmHstRegsWithGstShadow = 0;3014 pReNative->Core.bmHstRegsWithGstShadow = 0; 3014 3015 } 3015 3016 } … … 3279 3280 */ 3280 3281 uint8_t const iTmpReg = iemNativeRegAllocTmp(pReNative, &off); 3281 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);3282 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 3282 3283 3283 3284 off = iemNativeEmitLoadGprFromGpr(pReNative, off, iTmpReg, idxAddrReg); … … 3315 3316 */ 3316 3317 uint8_t const iTmpReg = iemNativeRegAllocTmp(pReNative, &off); 3317 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);3318 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 3318 3319 3319 3320 off = iemNativeEmitLoadGprImm64(pReNative, off, iTmpReg, UINT64_C(0x800000000000)); … … 3368 3369 (IEMNATIVEGSTREG)(kIemNativeGstReg_SegLimitFirst + idxSegReg), 3369 3370 kIemNativeGstRegUse_ForUpdate); 3370 AssertReturn(iTmpLimReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);3371 AssertReturn(iTmpLimReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 3371 3372 3372 3373 off = iemNativeEmitCmpGpr32WithGpr(pReNative, off, idxAddrReg, iTmpLimReg); … … 4085 4086 4086 4087 4088 /** 4089 * Start of the if-block, snapshotting the register and variable state. 4090 */ 4091 DECLINLINE(void) iemNativeCondStartIfBlock(PIEMRECOMPILERSTATE pReNative, uint32_t offIfBlock) 4092 { 4093 Assert(offIfBlock != UINT32_MAX); 4094 Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack)); 4095 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1]; 4096 Assert(!pEntry->fInElse); 4097 4098 /* Define the start of the IF block for disassembly. */ 4099 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 4100 iemNativeLabelCreate(pReNative, kIemNativeLabelType_If, offIfBlock, pReNative->paLabels[pEntry->idxLabelElse].uData); 4101 #else 4102 RT_NOREF(offIfBlock); 4103 #endif 4104 4105 /* Copy the initial state so we can restore it in the 'else' block. */ 4106 pEntry->InitialState = pReNative->Core; 4107 } 4108 4109 4087 4110 #define IEM_MC_ELSE() } while (0); \ 4088 4111 off = iemNativeEmitElse(pReNative, off); \ … … 4106 4129 pEntry->fInElse = true; 4107 4130 4131 /* Snapshot the core state so we can do a merge at the endif and restore 4132 the snapshot we took at the start of the if-block. */ 4133 pEntry->IfFinalState = pReNative->Core; 4134 pReNative->Core = pEntry->InitialState; 4135 4108 4136 return off; 4109 4137 } … … 4122 4150 PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1]; 4123 4151 4124 /* Define the endif label and maybe the else one if we're still in the 'if' part. */ 4152 /* 4153 * Now we have find common group with the core state at the end of the 4154 * if-final. Use the smallest common denominator and just drop anything 4155 * that isn't the same in both states. 4156 */ 4157 /** @todo We could, maybe, shuffle registers around if we thought it helpful, 4158 * which is why we're doing this at the end of the else-block. 4159 * But we'd need more info about future for that to be worth the effort. */ 4160 PCIEMNATIVECORESTATE const pOther = pEntry->fInElse ? &pEntry->IfFinalState : &pEntry->InitialState; 4161 if (memcmp(&pReNative->Core, pOther, sizeof(*pOther)) != 0) 4162 { 4163 /* shadow guest stuff first. */ 4164 uint64_t fGstRegs = pReNative->Core.bmGstRegShadows; 4165 if (fGstRegs) 4166 { 4167 Assert(pReNative->Core.bmHstRegsWithGstShadow != 0); 4168 do 4169 { 4170 unsigned idxGstReg = ASMBitFirstSetU64(fGstRegs) - 1; 4171 fGstRegs &= ~RT_BIT_64(idxGstReg); 4172 4173 uint8_t const idxHstReg = pReNative->Core.aidxGstRegShadows[idxGstReg]; 4174 if ( !(pOther->bmGstRegShadows & RT_BIT_64(idxGstReg)) 4175 || idxHstReg != pOther->aidxGstRegShadows[idxGstReg]) 4176 { 4177 Log12(("iemNativeEmitEndIf: dropping gst %#RX64 from hst %s\n", 4178 g_aGstShadowInfo[idxGstReg].pszName, g_apszIemNativeHstRegNames[idxHstReg])); 4179 iemNativeRegClearGstRegShadowing(pReNative, idxHstReg, off); 4180 } 4181 } while (fGstRegs); 4182 } 4183 else 4184 Assert(pReNative->Core.bmHstRegsWithGstShadow == 0); 4185 4186 /* Check variables next. For now we must require them to be identical 4187 or stuff we can recreate. */ 4188 Assert(pReNative->Core.u64ArgVars == pOther->u64ArgVars); 4189 uint32_t fVars = pReNative->Core.bmVars | pOther->bmVars; 4190 if (fVars) 4191 { 4192 uint32_t const fVarsMustRemove = pReNative->Core.bmVars ^ pOther->bmVars; 4193 do 4194 { 4195 unsigned idxVar = ASMBitFirstSetU32(fVars) - 1; 4196 fVars &= ~RT_BIT_32(idxVar); 4197 4198 if (!(fVarsMustRemove & RT_BIT_32(idxVar))) 4199 { 4200 if (pReNative->Core.aVars[idxVar].idxReg == pOther->aVars[idxVar].idxReg) 4201 continue; 4202 if (pReNative->Core.aVars[idxVar].enmKind != kIemNativeVarKind_Stack) 4203 { 4204 uint8_t const idxHstReg = pReNative->Core.aVars[idxVar].idxReg; 4205 if (idxHstReg != UINT8_MAX) 4206 { 4207 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg); 4208 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 4209 Log12(("iemNativeEmitEndIf: Dropping hst reg %s for var #%u\n", 4210 g_apszIemNativeHstRegNames[idxHstReg], idxVar)); 4211 } 4212 continue; 4213 } 4214 } 4215 else if (!(pReNative->Core.bmVars & RT_BIT_32(idxVar))) 4216 continue; 4217 4218 /* Irreconcilable, so drop it. */ 4219 uint8_t const idxHstReg = pReNative->Core.aVars[idxVar].idxReg; 4220 if (idxHstReg != UINT8_MAX) 4221 { 4222 pReNative->Core.bmHstRegs &= ~RT_BIT_32(idxHstReg); 4223 pReNative->Core.aVars[idxVar].idxReg = UINT8_MAX; 4224 Log12(("iemNativeEmitEndIf: Dropping hst reg %s for var #%u (also dropped)\n", 4225 g_apszIemNativeHstRegNames[idxHstReg], idxVar)); 4226 } 4227 Log11(("iemNativeEmitEndIf: Freeing variable #%u\n", idxVar)); 4228 pReNative->Core.bmVars &= ~RT_BIT_32(idxVar); 4229 } while (fVars); 4230 } 4231 4232 /* Finally, check that the host register allocations matches. */ 4233 AssertMsgReturn(pReNative->Core.bmHstRegs == pOther->bmHstRegs, 4234 ("Core.bmHstRegs=%#x pOther->bmHstRegs=%#x - %#x\n", 4235 pReNative->Core.bmHstRegs, pOther->bmHstRegs, pReNative->Core.bmHstRegs ^ pOther->bmHstRegs), 4236 UINT32_MAX); 4237 } 4238 4239 /* 4240 * Define the endif label and maybe the else one if we're still in the 'if' part. 4241 */ 4125 4242 if (!pEntry->fInElse) 4126 4243 iemNativeLabelDefine(pReNative, pEntry->idxLabelElse, off); … … 4160 4277 /* Free but don't flush the EFlags register. */ 4161 4278 iemNativeRegFreeTmp(pReNative, idxEflReg); 4279 4280 /* Make a copy of the core state now as we start the if-block. */ 4281 iemNativeCondStartIfBlock(pReNative, off); 4162 4282 4163 4283 return off; … … 4287 4407 { RT_STR_TUPLE("TYPE_NATIVE"), IEMTB_F_TYPE_NATIVE }, 4288 4408 }; 4289 for (unsigned i = 0; i < RT_ELEMENTS(s_aFlags) && fFlags; i++) 4290 if (s_aFlags[i].fFlag & fFlags) 4291 { 4292 AssertReturnStmt(off + 1 + s_aFlags[i].cchName + 1 <= cbBuf, pszBuf[off] = '\0', pszBuf); 4293 pszBuf[off++] = ' '; 4294 memcpy(&pszBuf[off], s_aFlags[i].pszName, s_aFlags[i].cchName); 4295 off += s_aFlags[i].cchName; 4296 fFlags &= ~s_aFlags[i].fFlag; 4297 } 4409 if (fFlags) 4410 for (unsigned i = 0; i < RT_ELEMENTS(s_aFlags); i++) 4411 if (s_aFlags[i].fFlag & fFlags) 4412 { 4413 AssertReturnStmt(off + 1 + s_aFlags[i].cchName + 1 <= cbBuf, pszBuf[off] = '\0', pszBuf); 4414 pszBuf[off++] = ' '; 4415 memcpy(&pszBuf[off], s_aFlags[i].pszName, s_aFlags[i].cchName); 4416 off += s_aFlags[i].cchName; 4417 fFlags &= ~s_aFlags[i].fFlag; 4418 if (!fFlags) 4419 break; 4420 } 4298 4421 pszBuf[off] = '\0'; 4299 4422 … … 4471 4594 case kIemTbDbgEntryType_Label: 4472 4595 { 4473 const char *pszName = "what_the_fudge"; 4474 bool fNumbered = pDbgInfo->aEntries[iDbgEntry].Label.uData != 0; 4596 const char *pszName = "what_the_fudge"; 4597 const char *pszCommment = ""; 4598 bool fNumbered = pDbgInfo->aEntries[iDbgEntry].Label.uData != 0; 4475 4599 switch ((IEMNATIVELABELTYPE)pDbgInfo->aEntries[iDbgEntry].Label.enmLabel) 4476 4600 { 4477 case kIemNativeLabelType_Return: pszName = "Return"; break; 4478 case kIemNativeLabelType_Else: pszName = "Else"; fNumbered = true; break; 4479 case kIemNativeLabelType_Endif: pszName = "Endif"; fNumbered = true; break; 4480 case kIemNativeLabelType_NonZeroRetOrPassUp: pszName = "NonZeroRetOrPassUp"; break; 4481 case kIemNativeLabelType_RaiseGp0: pszName = "RaiseGp0"; break; 4482 case kIemNativeLabelType_Invalid: break; 4483 case kIemNativeLabelType_End: break; 4601 case kIemNativeLabelType_Return: 4602 pszName = "Return"; 4603 break; 4604 case kIemNativeLabelType_If: 4605 pszName = "If"; 4606 fNumbered = true; 4607 break; 4608 case kIemNativeLabelType_Else: 4609 pszName = "Else"; 4610 fNumbered = true; 4611 pszComment = " ; regs state restored pre-if-block"; 4612 break; 4613 case kIemNativeLabelType_Endif: 4614 pszName = "Endif"; 4615 fNumbered = true; 4616 break; 4617 case kIemNativeLabelType_NonZeroRetOrPassUp: 4618 pszName = "NonZeroRetOrPassUp"; 4619 break; 4620 case kIemNativeLabelType_RaiseGp0: 4621 pszName = "RaiseGp0"; 4622 break; 4623 case kIemNativeLabelType_Invalid: 4624 case kIemNativeLabelType_End: 4625 break; 4484 4626 } 4485 4627 if (fNumbered) 4486 pHlp->pfnPrintf(pHlp, " %s_%u: \n", pszName, pDbgInfo->aEntries[iDbgEntry].Label.uData);4628 pHlp->pfnPrintf(pHlp, " %s_%u:%s\n", pszName, pDbgInfo->aEntries[iDbgEntry].Label.uData, pszComment); 4487 4629 else 4488 4630 pHlp->pfnPrintf(pHlp, " %s:\n", pszName); -
trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
r101505 r101557 1796 1796 for oThreadedFunction in self.aoThreadedFuncs: 1797 1797 if oThreadedFunction.oMcBlock.cLocals >= 0: 1798 # Counts. 1798 1799 assert oThreadedFunction.oMcBlock.cArgs >= 0; 1799 1800 cMaxVars = max(cMaxVars, oThreadedFunction.oMcBlock.cLocals); 1800 1801 cMaxArgs = max(cMaxArgs, oThreadedFunction.oMcBlock.cArgs); 1801 1802 cMaxVarsAndArgs = max(cMaxVarsAndArgs, oThreadedFunction.oMcBlock.cLocals + oThreadedFunction.oMcBlock.cArgs); 1803 if cMaxVarsAndArgs > 9: 1804 raise Exception('%s potentially uses too many variables / args: %u, max 10 - %u vars and %u args' 1805 % (oThreadedFunction.oMcBlock.oFunction.sName, cMaxVarsAndArgs, 1806 oThreadedFunction.oMcBlock.cLocals, oThreadedFunction.oMcBlock.cArgs)); 1802 1807 # Calc stack allocation size: 1803 1808 cbArgs = 0; -
trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
r101547 r101557 264 264 kIemNativeLabelType_Invalid = 0, 265 265 kIemNativeLabelType_Return, 266 #ifdef IEMNATIVE_WITH_TB_DEBUG_INFO 267 kIemNativeLabelType_If, 268 #endif 266 269 kIemNativeLabelType_Else, 267 270 kIemNativeLabelType_Endif, … … 477 480 478 481 /** 482 * Core state for the native recompiler, that is, things that needs careful 483 * handling when dealing with branches. 484 */ 485 typedef struct IEMNATIVECORESTATE 486 { 487 /** Allocation bitmap for aHstRegs. */ 488 uint32_t bmHstRegs; 489 490 /** Bitmap marking which host register contains guest register shadow copies. 491 * This is used during register allocation to try preserve copies. */ 492 uint32_t bmHstRegsWithGstShadow; 493 /** Bitmap marking valid entries in aidxGstRegShadows. */ 494 uint64_t bmGstRegShadows; 495 496 union 497 { 498 /** Index of variable arguments, UINT8_MAX if not valid. */ 499 uint8_t aidxArgVars[8]; 500 /** For more efficient resetting. */ 501 uint64_t u64ArgVars; 502 }; 503 504 /** Allocation bitmap for aVars. */ 505 uint32_t bmVars; 506 507 /** Maps a guest register to a host GPR (index by IEMNATIVEGSTREG). 508 * Entries are only valid if the corresponding bit in bmGstRegShadows is set. 509 * (A shadow copy of a guest register can only be held in a one host register, 510 * there are no duplicate copies or ambiguities like that). */ 511 uint8_t aidxGstRegShadows[kIemNativeGstReg_End]; 512 513 /** Host register allocation tracking. */ 514 IEMNATIVEHSTREG aHstRegs[IEMNATIVE_HST_GREG_COUNT]; 515 516 /** Variables and arguments. */ 517 IEMNATIVEVAR aVars[9]; 518 } IEMNATIVECORESTATE; 519 /** Pointer to core state. */ 520 typedef IEMNATIVECORESTATE *PIEMNATIVECORESTATE; 521 /** Pointer to const core state. */ 522 typedef IEMNATIVECORESTATE const *PCIEMNATIVECORESTATE; 523 524 525 /** 479 526 * Conditional stack entry. 480 527 */ … … 482 529 { 483 530 /** Set if we're in the "else" part, clear if we're in the "if" before it. */ 484 bool fInElse;531 bool fInElse; 485 532 /** The label for the IEM_MC_ELSE. */ 486 uint32_t idxLabelElse;533 uint32_t idxLabelElse; 487 534 /** The label for the IEM_MC_ENDIF. */ 488 uint32_t idxLabelEndIf; 535 uint32_t idxLabelEndIf; 536 /** The initial state snapshot as the if-block starts executing. */ 537 IEMNATIVECORESTATE InitialState; 538 /** The state snapshot at the end of the if-block. */ 539 IEMNATIVECORESTATE IfFinalState; 489 540 } IEMNATIVECOND; 490 541 /** Pointer to a condition stack entry. */ … … 504 555 uint32_t offInstrBufChecked; 505 556 #else 506 uint32_t uPadding ; /* We don't keep track of the size here... */557 uint32_t uPadding1; /* We don't keep track of the size here... */ 507 558 #endif 508 559 /** Fixed temporary code buffer for native recompilation. */ … … 531 582 /** Debug info. */ 532 583 PIEMTBDBG pDbgInfo; 533 #else534 uint32_t abPadding1[2];535 uintptr_t uPtrPadding2;536 584 #endif 537 585 … … 539 587 PCIEMTB pTbOrg; 540 588 541 /** Allocation bitmap fro aHstRegs. */542 uint32_t bmHstRegs;543 544 /** Bitmap marking which host register contains guest register shadow copies.545 * This is used during register allocation to try preserve copies. */546 uint32_t bmHstRegsWithGstShadow;547 /** Bitmap marking valid entries in aidxGstRegShadows. */548 uint64_t bmGstRegShadows;549 550 589 /** The current condition stack depth (aCondStack). */ 551 590 uint8_t cCondDepth; 552 uint8_t bPadding ;591 uint8_t bPadding2; 553 592 /** Condition sequence number (for generating unique labels). */ 554 593 uint16_t uCondSeqNo; 555 556 /** Allocation bitmap for aVars. */ 557 uint32_t bmVars; 558 union 559 { 560 /** Index of variable arguments, UINT8_MAX if not valid. */ 561 uint8_t aidxArgVars[8]; 562 /** For more efficient resetting. */ 563 uint64_t u64ArgVars; 564 }; 565 566 /** Host register allocation tracking. */ 567 IEMNATIVEHSTREG aHstRegs[IEMNATIVE_HST_GREG_COUNT]; 568 /** Maps a guest register to a host GPR (index by IEMNATIVEGSTREG). 569 * Entries are only valid if the corresponding bit in bmGstRegShadows is set. 570 * (A shadow copy of a guest register can only be held in a one host register, 571 * there are no duplicate copies or ambiguities like that). */ 572 uint8_t aidxGstRegShadows[kIemNativeGstReg_End]; 594 uint32_t uPadding3; 595 596 /** Core state requiring care with branches. */ 597 IEMNATIVECORESTATE Core; 573 598 574 599 /** The condition nesting stack. */ 575 IEMNATIVECOND aCondStack[4]; 576 577 /** Variables and arguments. */ 578 IEMNATIVEVAR aVars[16]; 600 IEMNATIVECOND aCondStack[2]; 579 601 } IEMRECOMPILERSTATE; 580 602 /** Pointer to a native recompiler state. */ … … 1521 1543 /* Best to use a temporary register to deal with this in the simplest way: */ 1522 1544 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint64_t)iAddend); 1523 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);1545 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 1524 1546 1525 1547 /* add dst, tmpreg */ … … 1548 1570 /* Use temporary register for the immediate. */ 1549 1571 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint64_t)iAddend); 1550 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);1572 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 1551 1573 1552 1574 /* add gprdst, gprdst, tmpreg */ … … 1602 1624 /* Use temporary register for the immediate. */ 1603 1625 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, (uint32_t)iAddend); 1604 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative-> aHstRegs), UINT32_MAX);1626 AssertReturn(iTmpReg < RT_ELEMENTS(pReNative->Core.aHstRegs), UINT32_MAX); 1605 1627 1606 1628 /* add gprdst, gprdst, tmpreg */
Note:
See TracChangeset
for help on using the changeset viewer.