VirtualBox

Changeset 103742 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Mar 9, 2024 2:01:04 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implemented iemNativeEmit_cmp_r_i_efl and enabled it for both hosts. Fixed bug in related code encoding shifted UImm12 constants on arm. bugref:10376

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h

    r103740 r103742  
    19871987{
    19881988    IEMOP_MNEMONIC(cmp_al_Ib, "cmp al,Ib");
    1989     IEMOP_BODY_BINARY_AL_Ib(cmp, 0);
     1989    IEMOP_BODY_BINARY_AL_Ib(cmp, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    19901990}
    19911991
     
    19981998{
    19991999    IEMOP_MNEMONIC(cmp_rAX_Iz, "cmp rAX,Iz");
    2000     IEMOP_BODY_BINARY_rAX_Iz_RO(cmp, 0);
     2000    IEMOP_BODY_BINARY_rAX_Iz_RO(cmp, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    20012001}
    20022002
     
    44644464{
    44654465    IEMOP_MNEMONIC(cmp_Eb_Ib, "cmp Eb,Ib");
    4466     IEMOP_BODY_BINARY_Eb_Ib_RO(cmp, 0);
     4466    IEMOP_BODY_BINARY_Eb_Ib_RO(cmp, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    44674467}
    44684468
     
    50375037{
    50385038    IEMOP_MNEMONIC(cmp_Ev_Iz, "cmp Ev,Iz");
    5039     IEMOP_BODY_BINARY_Ev_Iz_RO(cmp, 0);
     5039    IEMOP_BODY_BINARY_Ev_Iz_RO(cmp, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
    50405040}
    50415041
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h

    r103740 r103742  
    728728            pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
    729729        else if (uImmOp <= 0xfff000U && !(uImmOp & 0xfff))
    730             pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/,
    731                                                        true /*fShift12*/);
     730            pCodeBuf[off++] = Armv8A64MkInstrAddUImm12(idxRegDst, idxRegDst, uImmOp >> 12, cOpBits > 32 /*f64Bit*/,
     731                                                       true /*fSetFlags*/, true /*fShift12*/);
    732732        else
    733733        {
     
    932932            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
    933933        else if (uImmOp <= 0xfff000U && !(uImmOp & 0xfff))
    934             pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegDst, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/,
    935                                                        true /*fShift12*/);
     934            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegDst, idxRegDst, uImmOp >> 12, cOpBits > 32 /*f64Bit*/,
     935                                                       true /*fSetFlags*/, true /*fShift12*/);
    936936        else
    937937        {
     
    10331033                          uint8_t idxVarDst, uint64_t uImmOp, uint8_t idxVarEfl, uint8_t cOpBits, uint8_t cImmBits)
    10341034{
    1035     RT_NOREF(pReNative, off, idxVarDst, uImmOp, idxVarEfl, cOpBits, cImmBits);
     1035    uint8_t const idxRegDst = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
     1036
     1037#ifdef RT_ARCH_AMD64
     1038    /* On AMD64 we just use the correctly sized CMP instruction to get the right EFLAGS.SF value. */
     1039    PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 8);
     1040    off = iemNativeEmitAmd64OneByteModRmInstrRIEx(pCodeBuf, off, 0x80, 0x83, 0x81, cOpBits, cImmBits, 7, idxRegDst, uImmOp);
     1041    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1042
     1043    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     1044
     1045    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, UINT8_MAX);
     1046
     1047#elif defined(RT_ARCH_ARM64)
     1048    /* On ARM64 we'll need the actual result as well as both input operands in order
     1049       to calculate the right flags, even if we use SUBS and translates NZCV into
     1050       OF, CF, ZF and SF. */
     1051    uint8_t const   idxRegResult = iemNativeRegAllocTmp(pReNative, &off);
     1052    PIEMNATIVEINSTR pCodeBuf     = iemNativeInstrBufEnsure(pReNative, off, 8);
     1053    if (cOpBits >= 32)
     1054    {
     1055        if (uImmOp <= 0xfffU)
     1056            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegResult, idxRegDst, uImmOp, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
     1057        else if (uImmOp <= 0xfff000U && !(uImmOp & 0xfff))
     1058            pCodeBuf[off++] = Armv8A64MkInstrSubUImm12(idxRegResult, idxRegDst, uImmOp >> 12, cOpBits > 32 /*f64Bit*/,
     1059                                                       true /*fSetFlags*/, true /*fShift12*/);
     1060        else
     1061        {
     1062            uint8_t const idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     1063            pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     1064            pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegResult, idxRegDst, idxRegTmpImm, cOpBits > 32 /*f64Bit*/, true /*fSetFlags*/);
     1065            iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
     1066        }
     1067    }
     1068    else
     1069    {
     1070        /* Shift the operands up so we can perform a 32-bit operation and get all four flags. */
     1071        uint32_t const cShift       = 32 - cOpBits;
     1072        uint8_t const  idxRegTmpImm = iemNativeRegAllocTmpImm(pReNative, &off, uImmOp);
     1073        pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     1074        pCodeBuf[off++] = Armv8A64MkInstrLslImm(idxRegResult, idxRegDst,    cShift, false /*f64Bit*/);
     1075        pCodeBuf[off++] = Armv8A64MkInstrSubReg(idxRegResult, idxRegResult, idxRegTmpImm, false /*f64Bit*/, true /*fSetFlags*/, cShift);
     1076        pCodeBuf[off++] = Armv8A64MkInstrLsrImm(idxRegResult, idxRegResult, cShift, false /*f64Bit*/);
     1077        cOpBits = 32;
     1078        iemNativeRegFreeTmpImm(pReNative, idxRegTmpImm);
     1079    }
     1080    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     1081
     1082    off = iemNativeEmitEFlagsForArithmetic(pReNative, off, idxVarEfl, UINT8_MAX, cOpBits, idxRegResult,
     1083                                           idxRegDst, UINT8_MAX, true /*fInvertCarry*/, uImmOp);
     1084
     1085    iemNativeRegFreeTmp(pReNative, idxRegResult);
     1086    iemNativeVarRegisterRelease(pReNative, idxVarDst);
     1087    RT_NOREF(cImmBits);
     1088
     1089#else
     1090# error "port me"
     1091#endif
    10361092    return off;
    10371093}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette