Changeset 103555 in vbox for trunk/src/VBox/VMM/include
- Timestamp:
- Feb 24, 2024 2:14:09 AM (13 months ago)
- svn:sync-xref-src-repo-rev:
- 161905
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h
r103404 r103555 4411 4411 4412 4412 4413 /** 4414 * Emits code for OR'ing a 64-bit GPRs with a constant. 4415 */ 4416 DECL_INLINE_THROW(uint32_t) 4417 iemNativeEmitOrGprByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint64_t uImm) 4418 { 4419 #if defined(RT_ARCH_AMD64) 4420 if ((int64_t)uImm == (int8_t)uImm) 4421 { 4422 /* or Ev, imm8 */ 4423 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 4424 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_B); 4425 pbCodeBuf[off++] = 0x83; 4426 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7); 4427 pbCodeBuf[off++] = (uint8_t)uImm; 4428 } 4429 else if ((int64_t)uImm == (int32_t)uImm) 4430 { 4431 /* or Ev, imm32 */ 4432 uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 7); 4433 pbCodeBuf[off++] = X86_OP_REX_W | (iGprDst < 8 ? 0 : X86_OP_REX_B); 4434 pbCodeBuf[off++] = 0x81; 4435 pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7); 4436 pbCodeBuf[off++] = RT_BYTE1(uImm); 4437 pbCodeBuf[off++] = RT_BYTE2(uImm); 4438 pbCodeBuf[off++] = RT_BYTE3(uImm); 4439 pbCodeBuf[off++] = RT_BYTE4(uImm); 4440 } 4441 else 4442 { 4443 /* Use temporary register for the 64-bit immediate. */ 4444 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 4445 off = iemNativeEmitOrGprByGprEx(iemNativeInstrBufEnsure(pReNative, off, 3), off, iGprDst, iTmpReg); 4446 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 4447 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 4448 } 4449 4450 #elif defined(RT_ARCH_ARM64) 4451 uint32_t uImmR = 0; 4452 uint32_t uImmNandS = 0; 4453 if (Armv8A64ConvertMask64ToImmRImmS(uImm, &uImmNandS, &uImmR)) 4454 { 4455 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 4456 pu32CodeBuf[off++] = Armv8A64MkInstrOrrImm(iGprDst, iGprDst, uImmNandS, uImmR); 4457 } 4458 else 4459 { 4460 /* Use temporary register for the 64-bit immediate. */ 4461 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 4462 off = iemNativeEmitOrGprByGprEx(iemNativeInstrBufEnsure(pReNative, off, 1), off, iGprDst, iTmpReg); 4463 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 4464 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 4465 } 4466 4467 #else 4468 # error "Port me" 4469 #endif 4470 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 4471 return off; 4472 } 4473 4474 4475 /** 4476 * Emits code for OR'ing an 32-bit GPRs with a constant. 4477 * @note Bits 32 thru 63 in the destination will be zero after the operation. 4478 * @note For ARM64 this only supports @a uImm values that can be expressed using 4479 * the two 6-bit immediates of the OR instructions. The caller must make 4480 * sure this is possible! 4481 */ 4482 DECL_FORCE_INLINE_THROW(uint32_t) 4483 iemNativeEmitOrGpr32ByImmEx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t iGprDst, uint32_t uImm) 4484 { 4485 #if defined(RT_ARCH_AMD64) 4486 /* or Ev, imm */ 4487 if (iGprDst >= 8) 4488 pCodeBuf[off++] = X86_OP_REX_B; 4489 if ((int32_t)uImm == (int8_t)uImm) 4490 { 4491 pCodeBuf[off++] = 0x83; 4492 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7); 4493 pCodeBuf[off++] = (uint8_t)uImm; 4494 } 4495 else 4496 { 4497 pCodeBuf[off++] = 0x81; 4498 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, iGprDst & 7); 4499 pCodeBuf[off++] = RT_BYTE1(uImm); 4500 pCodeBuf[off++] = RT_BYTE2(uImm); 4501 pCodeBuf[off++] = RT_BYTE3(uImm); 4502 pCodeBuf[off++] = RT_BYTE4(uImm); 4503 } 4504 4505 #elif defined(RT_ARCH_ARM64) 4506 uint32_t uImmR = 0; 4507 uint32_t uImmNandS = 0; 4508 if (Armv8A64ConvertMask32ToImmRImmS(uImm, &uImmNandS, &uImmR)) 4509 pCodeBuf[off++] = Armv8A64MkInstrOrrImm(iGprDst, iGprDst, uImmNandS, uImmR, false /*f64Bit*/); 4510 else 4511 # ifdef IEM_WITH_THROW_CATCH 4512 AssertFailedStmt(IEMNATIVE_DO_LONGJMP(NULL, VERR_IEM_IPE_9)); 4513 # else 4514 AssertReleaseFailedStmt(off = UINT32_MAX); 4515 # endif 4516 4517 #else 4518 # error "Port me" 4519 #endif 4520 return off; 4521 } 4522 4523 4524 /** 4525 * Emits code for OR'ing an 32-bit GPRs with a constant. 4526 * 4527 * @note Bits 32 thru 63 in the destination will be zero after the operation. 4528 */ 4529 DECL_INLINE_THROW(uint32_t) 4530 iemNativeEmitOrGpr32ByImm(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGprDst, uint32_t uImm) 4531 { 4532 #if defined(RT_ARCH_AMD64) 4533 off = iemNativeEmitOrGpr32ByImmEx(iemNativeInstrBufEnsure(pReNative, off, 7), off, iGprDst, uImm); 4534 4535 #elif defined(RT_ARCH_ARM64) 4536 uint32_t uImmR = 0; 4537 uint32_t uImmNandS = 0; 4538 if (Armv8A64ConvertMask32ToImmRImmS(uImm, &uImmNandS, &uImmR)) 4539 { 4540 uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 4541 pu32CodeBuf[off++] = Armv8A64MkInstrOrrImm(iGprDst, iGprDst, uImmNandS, uImmR, false /*f64Bit*/); 4542 } 4543 else 4544 { 4545 /* Use temporary register for the 64-bit immediate. */ 4546 uint8_t iTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uImm); 4547 off = iemNativeEmitOrGpr32ByGpr(pReNative, off, iGprDst, iTmpReg); 4548 iemNativeRegFreeTmpImm(pReNative, iTmpReg); 4549 } 4550 4551 #else 4552 # error "Port me" 4553 #endif 4554 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 4555 return off; 4556 } 4557 4413 4558 4414 4559 /**
Note:
See TracChangeset
for help on using the changeset viewer.