VirtualBox

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


Ignore:
Timestamp:
Aug 30, 2013 12:54:04 AM (11 years ago)
Author:
vboxsync
Message:

IEM: Implemented 64-bit rol, ror, rcl, rcr, shl, shr, sar, shld, shrd and xadd for 32-bit hosts.

File:
1 edited

Legend:

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

    r48170 r48172  
    869869IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    870870{
    871     AssertFailed();
     871    cShift &= 63;
     872    if (cShift)
     873    {
     874        uint64_t uDst = *puDst;
     875        uint64_t uResult;
     876        uResult  = uDst << cShift;
     877        uResult |= uDst >> (64 - cShift);
     878        *puDst = uResult;
     879
     880        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     881           it the same way as for 1 bit shifts. */
     882        AssertCompile(X86_EFL_CF_BIT == 0);
     883        uint32_t fEfl   = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF);
     884        uint32_t fCarry = (uResult & 1);
     885        fEfl |= fCarry;
     886        fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
     887        *pfEFlags = fEfl;
     888    }
    872889}
    873890
     
    875892IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    876893{
    877     AssertFailed();
     894    cShift &= 63;
     895    if (cShift)
     896    {
     897        uint64_t uDst = *puDst;
     898        uint64_t uResult;
     899        uResult  = uDst >> cShift;
     900        uResult |= uDst << (64 - cShift);
     901        *puDst = uResult;
     902
     903        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     904           it the same way as for 1 bit shifts (OF = OF XOR New-CF). */
     905        AssertCompile(X86_EFL_CF_BIT == 0);
     906        uint32_t fEfl   = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF);
     907        uint32_t fCarry = (uResult >> 63) & X86_EFL_CF;
     908        fEfl |= fCarry;
     909        fEfl |= (((uResult >> 62) ^ fCarry) << X86_EFL_OF_BIT) & X86_EFL_OF;
     910        *pfEFlags = fEfl;
     911    }
    878912}
    879913
     
    881915IEM_DECL_IMPL_DEF(void, iemAImpl_rcl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    882916{
    883     AssertFailed();
     917    cShift &= 63;
     918    if (cShift)
     919    {
     920        uint32_t fEfl = *pfEFlags;
     921        uint64_t uDst = *puDst;
     922        uint64_t uResult;
     923        uResult = uDst << cShift;
     924        AssertCompile(X86_EFL_CF_BIT == 0);
     925        if (cShift > 1)
     926            uResult |= uDst >> (65 - cShift);
     927        uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (cShift - 1);
     928        *puDst = uResult;
     929
     930        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     931           it the same way as for 1 bit shifts. */
     932        uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF;
     933        fEfl &= ~(X86_EFL_CF | X86_EFL_OF);
     934        fEfl |= fCarry;
     935        fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
     936        *pfEFlags = fEfl;
     937    }
    884938}
    885939
     
    887941IEM_DECL_IMPL_DEF(void, iemAImpl_rcr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    888942{
    889     AssertFailed();
     943    cShift &= 63;
     944    if (cShift)
     945    {
     946        uint32_t fEfl = *pfEFlags;
     947        uint64_t uDst = *puDst;
     948        uint64_t uResult;
     949        uResult  = uDst >> cShift;
     950        AssertCompile(X86_EFL_CF_BIT == 0);
     951        if (cShift > 1)
     952            uResult |= uDst << (65 - cShift);
     953        uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (64 - cShift);
     954        *puDst = uResult;
     955
     956        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     957           it the same way as for 1 bit shifts. */
     958        uint32_t fCarry = (uDst >> (cShift - 1)) & X86_EFL_CF;
     959        fEfl &= ~(X86_EFL_CF | X86_EFL_OF);
     960        fEfl |= fCarry;
     961        fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
     962        *pfEFlags = fEfl;
     963    }
    890964}
    891965
     
    893967IEM_DECL_IMPL_DEF(void, iemAImpl_shl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    894968{
    895     AssertFailed();
     969    cShift &= 63;
     970    if (cShift)
     971    {
     972        uint64_t uDst = *puDst;
     973        uint64_t uResult = uDst << cShift;
     974        *puDst = uResult;
     975
     976        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     977           it the same way as for 1 bit shifts.  The AF bit is undefined, we
     978           always set it to zero atm. */
     979        AssertCompile(X86_EFL_CF_BIT == 0);
     980        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
     981        uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF;
     982        fEfl |= fCarry;
     983        fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
     984        fEfl |= X86_EFL_CALC_SF(uResult, 64);
     985        fEfl |= X86_EFL_CALC_ZF(uResult);
     986        fEfl |= g_afParity[uResult & 0xff];
     987        *pfEFlags = fEfl;
     988    }
    896989}
    897990
     
    899992IEM_DECL_IMPL_DEF(void, iemAImpl_shr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    900993{
    901     AssertFailed();
     994    cShift &= 63;
     995    if (cShift)
     996    {
     997        uint64_t uDst = *puDst;
     998        uint64_t uResult = uDst >> cShift;
     999        *puDst = uResult;
     1000
     1001        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     1002           it the same way as for 1 bit shifts.  The AF bit is undefined, we
     1003           always set it to zero atm. */
     1004        AssertCompile(X86_EFL_CF_BIT == 0);
     1005        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
     1006        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
     1007        fEfl |= (uDst >> 63) << X86_EFL_OF_BIT;
     1008        fEfl |= X86_EFL_CALC_SF(uResult, 64);
     1009        fEfl |= X86_EFL_CALC_ZF(uResult);
     1010        fEfl |= g_afParity[uResult & 0xff];
     1011        *pfEFlags = fEfl;
     1012    }
    9021013}
    9031014
     
    9051016IEM_DECL_IMPL_DEF(void, iemAImpl_sar_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    9061017{
    907     AssertFailed();
     1018    cShift &= 63;
     1019    if (cShift)
     1020    {
     1021        uint64_t uDst = *puDst;
     1022        uint64_t uResult = (int64_t)uDst >> cShift;
     1023        *puDst = uResult;
     1024
     1025        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     1026           it the same way as for 1 bit shifts (0).  The AF bit is undefined,
     1027           we always set it to zero atm. */
     1028        AssertCompile(X86_EFL_CF_BIT == 0);
     1029        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
     1030        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
     1031        fEfl |= X86_EFL_CALC_SF(uResult, 64);
     1032        fEfl |= X86_EFL_CALC_ZF(uResult);
     1033        fEfl |= g_afParity[uResult & 0xff];
     1034        *pfEFlags = fEfl;
     1035    }
    9081036}
    9091037
     
    9111039IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags))
    9121040{
    913     AssertFailed();
     1041    cShift &= 63;
     1042    if (cShift)
     1043    {
     1044        uint64_t uDst = *puDst;
     1045        uint64_t uResult;
     1046        uResult  = uDst << cShift;
     1047        uResult |= uSrc >> (64 - cShift);
     1048        *puDst = uResult;
     1049
     1050        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     1051           it the same way as for 1 bit shifts.  The AF bit is undefined,
     1052           we always set it to zero atm. */
     1053        AssertCompile(X86_EFL_CF_BIT == 0);
     1054        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
     1055        fEfl |= (uDst >> (64 - cShift)) & X86_EFL_CF;
     1056        fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT;
     1057        fEfl |= X86_EFL_CALC_SF(uResult, 64);
     1058        fEfl |= X86_EFL_CALC_ZF(uResult);
     1059        fEfl |= g_afParity[uResult & 0xff];
     1060        *pfEFlags = fEfl;
     1061    }
    9141062}
    9151063
     
    9171065IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags))
    9181066{
    919     AssertFailed();
     1067    cShift &= 63;
     1068    if (cShift)
     1069    {
     1070        uint64_t uDst = *puDst;
     1071        uint64_t uResult;
     1072        uResult  = uDst >> cShift;
     1073        uResult |= uSrc << (64 - cShift);
     1074        *puDst = uResult;
     1075
     1076        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
     1077           it the same way as for 1 bit shifts.  The AF bit is undefined,
     1078           we always set it to zero atm. */
     1079        AssertCompile(X86_EFL_CF_BIT == 0);
     1080        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
     1081        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
     1082        fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT;
     1083        fEfl |= X86_EFL_CALC_SF(uResult, 64);
     1084        fEfl |= X86_EFL_CALC_ZF(uResult);
     1085        fEfl |= g_afParity[uResult & 0xff];
     1086        *pfEFlags = fEfl;
     1087    }
    9201088}
    9211089
     
    9701138IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags))
    9711139{
    972     AssertFailed();
     1140    uint64_t uDst    = *puDst;
     1141    uint64_t uResult = uDst;
     1142    iemAImpl_add_u64(&uResult, *puReg, pfEFlags);
     1143    *puDst = uResult;
     1144    *puReg = uDst;
    9731145}
    9741146
     
    9781150    uint64_t uOld = ASMAtomicReadU64(puDst);
    9791151    uint64_t uTmpDst;
    980     uint64_t uTmpReg;
    9811152    uint32_t fEflTmp;
    9821153    do
    9831154    {
    9841155        uTmpDst = uOld;
    985         uTmpReg = *puReg;
    9861156        fEflTmp = *pfEFlags;
    987         iemAImpl_xadd_u64(&uTmpDst, &uTmpReg, &fEflTmp);
     1157        iemAImpl_add_u64(&uTmpDst, *puReg, pfEFlags);
    9881158    } while (ASMAtomicCmpXchgExU64(puDst, uTmpDst, uOld, &uOld));
    989     *puReg    = uTmpReg;
     1159    *puReg    = uOld;
    9901160    *pfEFlags = fEflTmp;
    9911161}
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