Changeset 102790 in vbox for trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
- Timestamp:
- Jan 9, 2024 1:41:28 AM (13 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r102785 r102790 1427 1427 1428 1428 1429 /** 1430 * Emits a gprdst[15:0] = gprsrc[15:0], preserving all other bits in the 1431 * destination. 1432 */ 1433 DECL_FORCE_INLINE(uint32_t) 1434 iemNativeEmitGprMergeInGpr16Ex(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t idxDst, uint8_t idxSrc) 1435 { 1436 #ifdef RT_ARCH_AMD64 1437 /* mov reg16, r/m16 */ 1438 pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 1439 if (idxDst >= 8 || idxSrc >= 8) 1440 pCodeBuf[off++] = (idxDst < 8 ? 0 : X86_OP_REX_R) | (idxSrc < 8 ? 0 : X86_OP_REX_B); 1441 pCodeBuf[off++] = 0x8b; 1442 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxDst & 7, idxSrc & 7); 1443 1444 #elif defined(RT_ARCH_ARM64) 1445 /* bfi w1, w2, 0, 16 - moves bits 15:0 from idxSrc to idxDst bits 15:0. */ 1446 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxDst, idxSrc, 0, 16); 1447 1448 #else 1449 # error "Port me!" 1450 #endif 1451 return off; 1452 } 1453 1454 1455 /** 1456 * Emits a gprdst[15:0] = gprsrc[15:0], preserving all other bits in the 1457 * destination. 1458 */ 1459 DECL_INLINE_THROW(uint32_t) 1460 iemNativeEmitGprMergeInGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxDst, uint8_t idxSrc) 1461 { 1462 #ifdef RT_ARCH_AMD64 1463 off = iemNativeEmitGprMergeInGpr16Ex(iemNativeInstrBufEnsure(pReNative, off, 4), off, idxDst, idxSrc); 1464 #elif defined(RT_ARCH_ARM64) 1465 off = iemNativeEmitGprMergeInGpr16Ex(iemNativeInstrBufEnsure(pReNative, off, 1), off, idxDst, idxSrc); 1466 #else 1467 # error "Port me!" 1468 #endif 1469 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 1470 return off; 1471 } 1472 1429 1473 1430 1474 #ifdef RT_ARCH_AMD64 … … 2814 2858 * so not suitable as a base for conditional jumps. 2815 2859 * 2860 * @note AMD64: Will only update the lower 16 bits of the register. 2816 2861 * @note ARM64: Will update the entire register. 2817 * @note AMD64: May perhaps only update the lower 16 bits of the register.2818 2862 * @note ARM64: Larger constants will require a temporary register. Failing to 2819 2863 * specify one when needed will trigger fatal assertion / throw. … … 3326 3370 return off; 3327 3371 } 3372 3373 3374 /** 3375 * Emits a 16-bit GPR add with a signed immediate addend. 3376 * 3377 * This will optimize using INC/DEC/whatever and ARM64 will not set flags, 3378 * so not suitable as a base for conditional jumps. 3379 * 3380 * @note AMD64: Will only update the lower 16 bits of the register. 3381 * @note ARM64: Will update the entire register. 3382 * @note ARM64: Larger constants will require a temporary register. Failing to 3383 * specify one when needed will trigger fatal assertion / throw. 3384 * @sa iemNativeEmitSubGpr16ImmEx 3385 */ 3386 DECL_FORCE_INLINE_THROW(uint32_t) 3387 iemNativeEmitAddGpr16ImmEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprDst, int16_t iAddend, 3388 uint8_t iGprTmp = UINT8_MAX) 3389 { 3390 #ifdef RT_ARCH_AMD64 3391 pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 3392 if (iGprDst >= 8) 3393 pCodeBuf[off++] = X86_OP_REX_B; 3394 if (iAddend == 1) 3395 { 3396 /* inc r/m16 */ 3397 pCodeBuf[off++] = 0xff; 3398 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7); 3399 } 3400 else if (iAddend == -1) 3401 { 3402 /* dec r/m16 */ 3403 pCodeBuf[off++] = 0xff; 3404 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7); 3405 } 3406 else if ((int8_t)iAddend == iAddend) 3407 { 3408 /* add r/m16, imm8 */ 3409 pCodeBuf[off++] = 0x83; 3410 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7); 3411 pCodeBuf[off++] = (uint8_t)iAddend; 3412 } 3413 else 3414 { 3415 /* add r/m16, imm16 */ 3416 pCodeBuf[off++] = 0x81; 3417 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprDst & 7); 3418 pCodeBuf[off++] = RT_BYTE1((uint16_t)iAddend); 3419 pCodeBuf[off++] = RT_BYTE2((uint16_t)iAddend); 3420 } 3421 RT_NOREF(iGprTmp); 3422 3423 #elif defined(RT_ARCH_ARM64) 3424 uint32_t uAbsAddend = RT_ABS(iAddend); 3425 if (uAbsAddend < 4096) 3426 { 3427 if (iAddend >= 0) 3428 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(iGprDst, iGprDst, uAbsAddend, false /*f64Bit*/); 3429 else 3430 pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(iGprDst, iGprDst, uAbsAddend, false /*f64Bit*/); 3431 } 3432 else if (uAbsAddend <= 0xfff000 && !(uAbsAddend & 0xfff)) 3433 { 3434 if (iAddend >= 0) 3435 pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(iGprDst, iGprDst, uAbsAddend >> 12, 3436 false /*f64Bit*/, false /*fSetFlags*/, true /*fShift*/); 3437 else 3438 pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(iGprDst, iGprDst, uAbsAddend >> 12, 3439 false /*f64Bit*/, false /*fSetFlags*/, true /*fShift*/); 3440 } 3441 else if (iGprTmp != UINT8_MAX) 3442 { 3443 off = iemNativeEmitLoadGpr32ImmEx(pCodeBuf, off, iGprTmp, (uint32_t)iAddend); 3444 pCodeBuf[off++] = Armv8A64MkInstrAddReg(iGprDst, iGprDst, iGprTmp, false /*f64Bit*/); 3445 } 3446 else 3447 # ifdef IEM_WITH_THROW_CATCH 3448 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9)); 3449 # else 3450 AssertReleaseFailedStmt(off = UINT32_MAX); 3451 # endif 3452 pCodeBuf[off++] = Armv8A64MkInstrAndImm(iGprDst, iGprDst, 15, 0, false /*f64Bit*/); 3453 3454 #else 3455 # error "Port me" 3456 #endif 3457 return off; 3458 } 3459 3328 3460 3329 3461
Note:
See TracChangeset
for help on using the changeset viewer.