Changeset 103675 in vbox
- Timestamp:
- Mar 5, 2024 2:10:37 AM (9 months ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/armv8.h
r103606 r103675 435 435 /** ICC_IGRPEN1_EL1 register - RW. */ 436 436 #define ARMV8_AARCH64_SYSREG_ICC_IGRPEN1_EL1 ARMV8_AARCH64_SYSREG_ID_CREATE(3, 0, 12, 12, 7) 437 438 /** NZCV - Status Flags - ??. */ 439 #define ARMV8_AARCH64_SYSREG_NZCV ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 0) 440 /** DAIF - Interrupt Mask Bits - ??. */ 441 #define ARMV8_AARCH64_SYSREG_DAIF ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 1) 442 /** SVCR - Streaming Vector Control Register - ??. */ 443 #define ARMV8_AARCH64_SYSREG_SVCR ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 2) 444 /** DIT - Data Independent Timing - ??. */ 445 #define ARMV8_AARCH64_SYSREG_DIT ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 5) 446 /** SSBS - Speculative Store Bypass Safe - ??. */ 447 #define ARMV8_AARCH64_SYSREG_SSBS ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 6) 448 /** TCO - Tag Check Override - ??. */ 449 #define ARMV8_AARCH64_SYSREG_TCO ARMV8_AARCH64_SYSREG_ID_CREATE(3, 3, 4, 2, 7) 437 450 438 451 /** CNTV_CTL_EL0 register - RW. */ … … 2226 2239 /** A64: Insert pointer authentication code into LR using XZR and key B. */ 2227 2240 #define ARMV8_A64_INSTR_PACIBZ UINT32_C(0xd503235f) 2241 /** A64: Invert the carry flag (PSTATE.C). */ 2242 #define ARMV8_A64_INSTR_CFINV UINT32_C(0xd500401f) 2228 2243 2229 2244 … … 3744 3759 3745 3760 return ((uint32_t)f64Bit << 31) 3746 | (UINT32_C(0x5ac00800))3761 | UINT32_C(0x5ac00800) 3747 3762 | ((uint32_t)f64Bit << 10) 3748 3763 | (iRegSrc << 5) … … 3764 3779 3765 3780 return ((uint32_t)f64Bit << 31) 3766 | (UINT32_C(0x5ac00400))3781 | UINT32_C(0x5ac00400) 3767 3782 | (iRegSrc << 5) 3768 3783 | iRegDst; … … 3770 3785 3771 3786 3787 /** 3788 * A64: Encodes SETF8 & SETF16. 3789 * 3790 * @returns The encoded instruction. 3791 * @param iRegResult The register holding the result. SP is NOT valid. 3792 * @param f16Bit Set for SETF16, clear for SETF8. 3793 */ 3794 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrSetF8SetF16(uint32_t iRegResult, bool f16Bit) 3795 { 3796 Assert(iRegResult < 32); 3797 3798 return UINT32_C(0x3a00080d) 3799 | ((uint32_t)f16Bit << 14) 3800 | (iRegResult << 5); 3801 } 3802 3803 3804 /** 3805 * A64: Encodes MRS (for reading a system register into a GPR). 3806 * 3807 * @returns The encoded instruction. 3808 * @param iRegDst The register to put the result into. SP is NOT valid. 3809 * @param idSysReg The system register ID (ARMV8_AARCH64_SYSREG_XXX), 3810 * IPRT specific format, of the register to read. 3811 */ 3812 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrMrs(uint32_t iRegDst, uint32_t idSysReg) 3813 { 3814 Assert(iRegDst < 32); 3815 Assert(idSysReg < RT_BIT_32(16) && (idSysReg & RT_BIT_32(15))); 3816 3817 /* Note. The top bit of idSysReg must always be set and is also set in 3818 0xd5300000, otherwise we'll be encoding a different instruction. */ 3819 return UINT32_C(0xd5300000) 3820 | (idSysReg << 5) 3821 | iRegDst; 3822 } 3823 3824 3825 /** 3826 * A64: Encodes MSR (for writing a GPR to a system register). 3827 * 3828 * @returns The encoded instruction. 3829 * @param iRegSrc The register which value to write. SP is NOT valid. 3830 * @param idSysReg The system register ID (ARMV8_AARCH64_SYSREG_XXX), 3831 * IPRT specific format, of the register to write. 3832 */ 3833 DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrMsr(uint32_t iRegSrc, uint32_t idSysReg) 3834 { 3835 Assert(iRegSrc < 32); 3836 Assert(idSysReg < RT_BIT_32(16) && (idSysReg & RT_BIT_32(15))); 3837 3838 /* Note. The top bit of idSysReg must always be set and is also set in 3839 0xd5100000, otherwise we'll be encoding a different instruction. */ 3840 return UINT32_C(0xd5100000) 3841 | (idSysReg << 5) 3842 | iRegSrc; 3843 } 3844 3845 3772 3846 /** @} */ 3773 3847 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h
r103658 r103675 1463 1463 { 1464 1464 IEMOP_MNEMONIC2(MR, SUB, sub, Eb, Gb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES | IEMOPHINT_LOCK_ALLOWED); 1465 IEMOP_BODY_BINARY_rm_r8_RW(iemAImpl_sub_u8, iemAImpl_sub_u8_locked, sub, 0, 0);1465 IEMOP_BODY_BINARY_rm_r8_RW(iemAImpl_sub_u8, iemAImpl_sub_u8_locked, sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0); 1466 1466 } 1467 1467 … … 1475 1475 { 1476 1476 IEMOP_MNEMONIC2(MR, SUB, sub, Ev, Gv, DISOPTYPE_HARMLESS, IEMOPHINT_LOCK_ALLOWED); 1477 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, sub, 0, 0);1477 IEMOP_BODY_BINARY_rm_rv_RW( iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64, 0); 1478 1478 IEMOP_BODY_BINARY_rm_rv_LOCKED(iemAImpl_sub_u16_locked, iemAImpl_sub_u32_locked, iemAImpl_sub_u64_locked); 1479 1479 } … … 1488 1488 { 1489 1489 IEMOP_MNEMONIC2(RM, SUB, sub, Gb, Eb, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZES); 1490 IEMOP_BODY_BINARY_r8_rm(iemAImpl_sub_u8, sub, 0);1490 IEMOP_BODY_BINARY_r8_rm(iemAImpl_sub_u8, sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64); 1491 1491 } 1492 1492 … … 1501 1501 IEMOP_MNEMONIC2(RM, SUB, sub, Gv, Ev, DISOPTYPE_HARMLESS, 0); 1502 1502 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); 1503 IEMOP_BODY_BINARY_rv_rm(bRm, iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, 1, 0, sub, 0);1503 IEMOP_BODY_BINARY_rv_rm(bRm, iemAImpl_sub_u16, iemAImpl_sub_u32, iemAImpl_sub_u64, 1, 0, sub, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64); 1504 1504 } 1505 1505 -
trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
r103657 r103675 33 33 34 34 35 #ifdef RT_ARCH_AMD64 36 DECL_FORCE_INLINE(uint32_t) 37 iemNativeEmitAmd64ModRmInstrRREx(PIEMNATIVEINSTR pCodeBuf, uint32_t off, uint8_t bOpcode8, uint8_t bOpcodeOther, 38 uint8_t cOpBits, uint8_t idxRegReg, uint8_t idxRegRm) 39 { 40 Assert(idxRegReg < 16); Assert(idxRegRm < 16); 41 switch (cOpBits) 42 { 43 case 16: 44 pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; 45 RT_FALL_THRU(); 46 case 32: 47 if (idxRegReg >= 8 || idxRegRm >= 8) 48 pCodeBuf[off++] = (idxRegReg >= 8 ? X86_OP_REX_R : 0) | (idxRegRm >= 8 ? X86_OP_REX_B : 0); 49 pCodeBuf[off++] = bOpcodeOther; 50 break; 51 52 default: AssertFailed(); RT_FALL_THRU(); 53 case 64: 54 pCodeBuf[off++] = X86_OP_REX_W | (idxRegReg >= 8 ? X86_OP_REX_R : 0) | (idxRegRm >= 8 ? X86_OP_REX_B : 0); 55 pCodeBuf[off++] = bOpcodeOther; 56 break; 57 58 case 8: 59 if (idxRegReg >= 8 || idxRegRm >= 8) 60 pCodeBuf[off++] = (idxRegReg >= 8 ? X86_OP_REX_R : 0) | (idxRegRm >= 8 ? X86_OP_REX_B : 0); 61 else if (idxRegReg >= 4 || idxRegRm >= 4) 62 pCodeBuf[off++] = X86_OP_REX; 63 pCodeBuf[off++] = bOpcode8; 64 break; 65 } 66 pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, idxRegReg & 7, idxRegRm & 7); 67 return off; 68 } 69 #endif /* RT_ARCH_AMD64 */ 70 71 35 72 /** 36 * This is an implementation of IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGICAL 37 * and friends. 73 * This is an implementation of IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGICAL. 38 74 * 39 75 * It takes liveness stuff into account. … … 121 157 } 122 158 return off; 159 } 160 161 162 /** 163 * This is an implementation of IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC. 164 * 165 * It takes liveness stuff into account. 166 */ 167 DECL_FORCE_INLINE_THROW(uint32_t) 168 iemNativeEmitEFlagsForArithmetic(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVarEfl 169 #ifndef RT_ARCH_AMD64 170 , uint8_t cOpBits, uint8_t idxRegResult, uint8_t idxRegDstIn, uint8_t idxRegSrc, bool fNativeFlags 171 #endif 172 ) 173 { 174 #ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS 175 if (1) /** @todo check if all bits are clobbered. */ 176 #endif 177 { 178 #ifdef RT_ARCH_AMD64 179 /* 180 * Collect flags and merge them with eflags. 181 */ 182 PIEMNATIVEINSTR pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); 183 /* pushf - do this before any reg allocations as they may emit instructions too. */ 184 pCodeBuf[off++] = 0x9c; 185 186 uint8_t const idxRegEfl = iemNativeVarRegisterAcquire(pReNative, idxVarEfl, &off, true /*fInitialized*/); 187 uint8_t const idxTmpReg = iemNativeRegAllocTmp(pReNative, &off); 188 pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 2 + 7 + 7 + 3); 189 /* pop tmp */ 190 if (idxTmpReg >= 8) 191 pCodeBuf[off++] = X86_OP_REX_B; 192 pCodeBuf[off++] = 0x58 + (idxTmpReg & 7); 193 /* Isolate the flags we want. */ 194 off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxTmpReg, X86_EFL_STATUS_BITS); 195 /* Clear the status bits in EFLs. */ 196 off = iemNativeEmitAndGpr32ByImmEx(pCodeBuf, off, idxRegEfl, ~X86_EFL_STATUS_BITS); 197 /* OR in the flags we collected. */ 198 off = iemNativeEmitOrGpr32ByGprEx(pCodeBuf, off, idxRegEfl, idxTmpReg); 199 iemNativeVarRegisterRelease(pReNative, idxVarEfl); 200 iemNativeRegFreeTmp(pReNative, idxTmpReg); 201 202 #elif defined(RT_ARCH_ARM64) 203 /* 204 * Calculate flags. 205 */ 206 uint8_t const idxRegEfl = iemNativeVarRegisterAcquire(pReNative, idxVarEfl, &off, true /*fInitialized*/); 207 uint8_t const idxTmpReg = iemNativeRegAllocTmp(pReNative, &off); 208 PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 18); 209 210 if (fNativeFlags && cOpBits >= 32) 211 { 212 /* Invert CF (stored inved on ARM) and load the flags into the temporary register. */ 213 pCodeBuf[off++] = ARMV8_A64_INSTR_CFINV; 214 pCodeBuf[off++] = Armv8A64MkInstrMrs(idxTmpReg, ARMV8_AARCH64_SYSREG_NZCV); /* Bits: 31=N; 30=Z; 29=C; 28=V; */ 215 216 /* V -> OF */ 217 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, 28); 218 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_OF_BIT, 1, false /*f64Bit*/); 219 220 /* C -> CF */ 221 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, 1); 222 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_CF_BIT, 1, false /*f64Bit*/); 223 224 /* N,Z -> SF,ZF */ 225 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, 1); 226 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_ZF_BIT, 2, false /*f64Bit*/); 227 } 228 else 229 { 230 #if 0 231 pCodeBuf[off++] = Armv8A64MkInstrSetF8SetF16(idxRegResult, cOpBits > 8); 232 pCodeBuf[off++] = Armv8A64MkInstrMrs(idxTmpReg, ARMV8_AARCH64_SYSREG_NZCV); /* Bits: 31=N; 30=Z; 29=C; 28=V; */ 233 234 /* V -> OF */ 235 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, 28); 236 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_OF_BIT, 1, false /*f64Bit*/); 237 238 /* N,Z -> SF,ZF */ 239 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, 2); 240 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_ZF_BIT, 2, false /*f64Bit*/); 241 #else 242 pCodeBuf[off++] = Armv8A64MkInstrBrk(0x1010); 243 #endif 244 } 245 246 /* Calculate 8-bit parity of the result. */ 247 pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxRegResult, idxRegResult, false /*f64Bit*/, 248 4 /*offShift6*/, kArmv8A64InstrShift_Lsr); 249 pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg, idxTmpReg, false /*f64Bit*/, 250 2 /*offShift6*/, kArmv8A64InstrShift_Lsr); 251 pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg, idxTmpReg, false /*f64Bit*/, 252 1 /*offShift6*/, kArmv8A64InstrShift_Lsr); 253 Assert(Armv8A64ConvertImmRImmS2Mask32(0, 0) == 1); 254 pCodeBuf[off++] = Armv8A64MkInstrEorImm(idxTmpReg, idxTmpReg, 0, 0, false /*f64Bit*/); 255 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_PF_BIT, 1, false /*f64Bit*/); 256 257 /* Calculate auxilary carry/borrow. This is related to 8-bit BCD.*/ 258 pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxRegDstIn, idxRegSrc, false /*f64Bit*/); 259 pCodeBuf[off++] = Armv8A64MkInstrEor(idxTmpReg, idxTmpReg, idxRegResult, false /*f64Bit*/); 260 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxTmpReg, idxTmpReg, X86_EFL_AF_BIT, false /*f64Bit*/); 261 pCodeBuf[off++] = Armv8A64MkInstrBfi(idxRegEfl, idxTmpReg, X86_EFL_AF_BIT, 1, false /*f64Bit*/); 262 263 iemNativeVarRegisterRelease(pReNative, idxVarEfl); 264 iemNativeRegFreeTmp(pReNative, idxTmpReg); 265 #else 266 # error "port me" 267 #endif 268 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 269 } 270 return off; 271 123 272 } 124 273 … … 405 554 uint8_t idxVarDst, uint8_t idxVarSrc, uint8_t idxVarEfl, uint8_t cOpBits) 406 555 { 407 RT_NOREF(idxVarDst, idxVarSrc, idxVarEfl, cOpBits); 408 AssertFailed(); 409 return iemNativeEmitBrk(pReNative, off, 0x666); 556 /* 557 * The SUB instruction will set all flags. 558 */ 559 uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/); 560 uint8_t const idxRegSrc = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/); 561 562 #ifdef RT_ARCH_ARM64 563 /* On ARM64 we'll need the two input operands as well as the result in order 564 to calculate the right flags, even if we use SUBS and translates NZCV into 565 OF, CF, ZF and SF. */ 566 567 /* Copy idxRegDst. */ 568 uint8_t const idxRegDstIn = iemNativeRegAllocTmp(pReNative, &off); 569 PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4); 570 571 /* Do the SUB setting flags. */ 572 if (cOpBits >= 32) 573 { 574 off = iemNativeEmitLoadGprFromGprEx(pCodeBuf, off, idxRegDstIn, idxRegDst); 575 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst, idxRegDst, idxRegSrc, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/); 576 } 577 else 578 { 579 /* Shift the operands up so we can perform a 32-bit operation and get all four flags. */ 580 uint32_t const cShift = 32 - cOpBits; 581 pCodeBuf[off++] = Armv8A64MkInstrOrr(idxRegDstIn, ARMV8_A64_REG_XZR, idxRegDst, false /*f64Bit*/, cShift); 582 pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegDst, idxRegDstIn, idxRegSrc, cOpBits > 32 /*f64Bit*/, 583 true /*fSetFlags*/, cShift); 584 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDstIn, idxRegDstIn, cShift, false /*f64Bit*/); 585 pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegDst, idxRegDst, cShift, false /*f64Bit*/); 586 } 587 588 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 589 590 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, RT_MAX(cOpBits, 32), idxRegDst, 591 idxRegDstIn, idxRegSrc, true /*fNativeFlags*/); 592 593 iemNativeRegFreeTmp(pReNative, idxRegDstIn); 594 iemNativeVarRegisterRelease(pReNative, idxVarSrc); 595 iemNativeVarRegisterRelease(pReNative, idxVarDst); 596 597 #elif defined(RT_ARCH_AMD64) 598 /* On AMD64 we must use the correctly sized AND instructions to get the 599 right EFLAGS.SF value, while the rest will just lump 16-bit and 8-bit 600 in the 32-bit ones. */ 601 off = iemNativeEmitAmd64ModRmInstrRREx(iemNativeInstrBufEnsure(pReNative, off, 4), off, 602 0x2a, 0x2b, cOpBits, idxRegDst, idxRegSrc); 603 IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); 604 605 iemNativeVarRegisterRelease(pReNative, idxVarSrc); 606 iemNativeVarRegisterRelease(pReNative, idxVarDst); 607 608 off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl); 609 610 #else 611 # error "port me" 612 #endif 613 return off; 410 614 } 411 615
Note:
See TracChangeset
for help on using the changeset viewer.