VirtualBox

Changeset 93792 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 16, 2022 1:30:16 PM (3 years ago)
Author:
vboxsync
Message:

VMM/IEM: Working on adding missing C version of IEMAllAImpl.asm functions. bugref:9898

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r93115 r93792  
    11021102
    11031103
    1104 ;;
    1105 ; Macro for implementing memory fence operation.
    1106 ;
    1107 ; No return value, no operands or anything.
    1108 ;
    1109 ; @param        1      The instruction.
    1110 ;
    1111 %macro IEMIMPL_MEM_FENCE 1
    1112 BEGINCODE
    1113 BEGINPROC_FASTCALL iemAImpl_ %+ %1, 0
    1114         %1
    1115         ret
    1116 ENDPROC iemAImpl_ %+ %1
    1117 %endmacro
    1118 
    1119 IEMIMPL_MEM_FENCE lfence
    1120 IEMIMPL_MEM_FENCE sfence
    1121 IEMIMPL_MEM_FENCE mfence
    1122 
    1123 ;;
    1124 ; Alternative for non-SSE2 host.
    1125 ;
    1126 BEGINPROC_FASTCALL iemAImpl_alt_mem_fence, 0
    1127         push    xAX
    1128         xchg    xAX, [xSP]
    1129         add     xSP, xCB
    1130         ret
    1131 ENDPROC iemAImpl_alt_mem_fence
    1132 
     1104;
     1105; BSWAP. No flag changes.
     1106;
     1107; Each function takes one argument, pointer to the value to bswap
     1108; (input/output). They all return void.
     1109;
     1110BEGINPROC_FASTCALL iemAImpl_bswap_u16, 4
     1111        PROLOGUE_1_ARGS
     1112        mov     T0_32, [A0]             ; just in case any of the upper bits are used.
     1113        db 66h
     1114        bswap   T0_32
     1115        mov     [A0], T0_32
     1116        EPILOGUE_1_ARGS
     1117ENDPROC iemAImpl_bswap_u16
     1118
     1119BEGINPROC_FASTCALL iemAImpl_bswap_u32, 4
     1120        PROLOGUE_1_ARGS
     1121        mov     T0_32, [A0]
     1122        bswap   T0_32
     1123        mov     [A0], T0_32
     1124        EPILOGUE_1_ARGS
     1125ENDPROC iemAImpl_bswap_u32
     1126
     1127BEGINPROC_FASTCALL iemAImpl_bswap_u64, 4
     1128%ifdef RT_ARCH_AMD64
     1129        PROLOGUE_1_ARGS
     1130        mov     T0, [A0]
     1131        bswap   T0
     1132        mov     [A0], T0
     1133        EPILOGUE_1_ARGS
     1134%else
     1135        PROLOGUE_1_ARGS
     1136        mov     T0, [A0]
     1137        mov     T1, [A0 + 4]
     1138        bswap   T0
     1139        bswap   T1
     1140        mov     [A0 + 4], T0
     1141        mov     [A0], T1
     1142        EPILOGUE_1_ARGS
     1143%endif
     1144ENDPROC iemAImpl_bswap_u64
    11331145
    11341146
     
    17441756
    17451757
    1746 ;
    1747 ; BSWAP. No flag changes.
    1748 ;
    1749 ; Each function takes one argument, pointer to the value to bswap
    1750 ; (input/output). They all return void.
    1751 ;
    1752 BEGINPROC_FASTCALL iemAImpl_bswap_u16, 4
    1753         PROLOGUE_1_ARGS
    1754         mov     T0_32, [A0]             ; just in case any of the upper bits are used.
    1755         db 66h
    1756         bswap   T0_32
    1757         mov     [A0], T0_32
    1758         EPILOGUE_1_ARGS
    1759 ENDPROC iemAImpl_bswap_u16
    1760 
    1761 BEGINPROC_FASTCALL iemAImpl_bswap_u32, 4
    1762         PROLOGUE_1_ARGS
    1763         mov     T0_32, [A0]
    1764         bswap   T0_32
    1765         mov     [A0], T0_32
    1766         EPILOGUE_1_ARGS
    1767 ENDPROC iemAImpl_bswap_u32
    1768 
    1769 BEGINPROC_FASTCALL iemAImpl_bswap_u64, 4
    1770 %ifdef RT_ARCH_AMD64
    1771         PROLOGUE_1_ARGS
    1772         mov     T0, [A0]
    1773         bswap   T0
    1774         mov     [A0], T0
    1775         EPILOGUE_1_ARGS
    1776 %else
    1777         PROLOGUE_1_ARGS
    1778         mov     T0, [A0]
    1779         mov     T1, [A0 + 4]
    1780         bswap   T0
    1781         bswap   T1
    1782         mov     [A0 + 4], T0
    1783         mov     [A0], T1
    1784         EPILOGUE_1_ARGS
    1785 %endif
    1786 ENDPROC iemAImpl_bswap_u64
     1758;;
     1759; Macro for implementing memory fence operation.
     1760;
     1761; No return value, no operands or anything.
     1762;
     1763; @param        1      The instruction.
     1764;
     1765%macro IEMIMPL_MEM_FENCE 1
     1766BEGINCODE
     1767BEGINPROC_FASTCALL iemAImpl_ %+ %1, 0
     1768        %1
     1769        ret
     1770ENDPROC iemAImpl_ %+ %1
     1771%endmacro
     1772
     1773IEMIMPL_MEM_FENCE lfence
     1774IEMIMPL_MEM_FENCE sfence
     1775IEMIMPL_MEM_FENCE mfence
     1776
     1777;;
     1778; Alternative for non-SSE2 host.
     1779;
     1780BEGINPROC_FASTCALL iemAImpl_alt_mem_fence, 0
     1781        push    xAX
     1782        xchg    xAX, [xSP]
     1783        add     xSP, xCB
     1784        ret
     1785ENDPROC iemAImpl_alt_mem_fence
    17871786
    17881787
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r93786 r93792  
    22812281*********************************************************************************************************************************/
    22822282
     2283/*
     2284 * ROL
     2285 */
     2286
     2287/**
     2288 * Updates the status bits (OF and CF) for an ROL instruction.
     2289 *
     2290 * @returns Status bits.
     2291 * @param   a_pfEFlags      Pointer to the 32-bit EFLAGS value to update.
     2292 * @param   a_uResult       Unsigned result value.
     2293 * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
     2294 */
     2295#define IEM_EFL_UPDATE_STATUS_BITS_FOR_ROL(a_pfEFlags, a_uResult, a_cBitsWidth) do { \
     2296        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2297           it the same way as for 1 bit shifts. */ \
     2298        AssertCompile(X86_EFL_CF_BIT == 0); \
     2299        uint32_t fEflTmp = *(a_pfEFlags); \
     2300        fEflTmp &= ~(X86_EFL_CF | X86_EFL_OF); \
     2301        uint32_t const fCarry = ((a_uResult) & X86_EFL_CF); \
     2302        fEflTmp |= fCarry; \
     2303        fEflTmp |= (((a_uResult) >> (a_cBitsWidth - 1)) ^ fCarry) << X86_EFL_OF_BIT; \
     2304        *(a_pfEFlags) = fEflTmp; \
     2305    } while (0)
     2306
    22832307IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    22842308{
     
    22862310    if (cShift)
    22872311    {
    2288         uint64_t uDst = *puDst;
    2289         uint64_t uResult;
    2290         uResult  = uDst << cShift;
    2291         uResult |= uDst >> (64 - cShift);
     2312        uint64_t uResult = ASMRotateLeftU64(*puDst, cShift);
    22922313        *puDst = uResult;
    2293 
    2294         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2295            it the same way as for 1 bit shifts. */
    2296         AssertCompile(X86_EFL_CF_BIT == 0);
    2297         uint32_t fEfl   = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF);
    2298         uint32_t fCarry = (uResult & 1);
    2299         fEfl |= fCarry;
    2300         fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
    2301         *pfEFlags = fEfl;
    2302     }
    2303 }
    2304 
     2314        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROL(pfEFlags, uResult, 64);
     2315    }
     2316}
     2317
     2318# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2319
     2320IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u32,(uint32_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2321{
     2322    cShift &= 31;
     2323    if (cShift)
     2324    {
     2325        uint32_t uResult = ASMRotateLeftU32(*puDst, cShift);
     2326        *puDst = uResult;
     2327        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROL(pfEFlags, uResult, 32);
     2328    }
     2329}
     2330
     2331
     2332IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u16,(uint16_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2333{
     2334    cShift &= 15;
     2335    if (cShift)
     2336    {
     2337        uint16_t uDst = *puDst;
     2338        uint16_t uResult = (uDst << cShift) | (uDst >> (16 - cShift));
     2339        *puDst = uResult;
     2340        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROL(pfEFlags, uResult, 16);
     2341    }
     2342}
     2343
     2344
     2345IEM_DECL_IMPL_DEF(void, iemAImpl_rol_u8,(uint8_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2346{
     2347    cShift &= 7;
     2348    if (cShift)
     2349    {
     2350        uint8_t uDst = *puDst;
     2351        uint8_t uResult = (uDst << cShift) | (uDst >> (8 - cShift));
     2352        *puDst = uResult;
     2353        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROL(pfEFlags, uResult, 8);
     2354    }
     2355}
     2356
     2357# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     2358
     2359
     2360/*
     2361 * ROR
     2362 */
     2363
     2364/**
     2365 * Updates the status bits (OF and CF) for an ROL instruction.
     2366 *
     2367 * @returns Status bits.
     2368 * @param   a_pfEFlags      Pointer to the 32-bit EFLAGS value to update.
     2369 * @param   a_uResult       Unsigned result value.
     2370 * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
     2371 */
     2372#define IEM_EFL_UPDATE_STATUS_BITS_FOR_ROR(a_pfEFlags, a_uResult, a_cBitsWidth) do { \
     2373        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2374           it the same way as for 1 bit shifts. */ \
     2375        AssertCompile(X86_EFL_CF_BIT == 0); \
     2376        uint32_t fEflTmp = *(a_pfEFlags); \
     2377        fEflTmp &= ~(X86_EFL_CF | X86_EFL_OF); \
     2378        uint32_t const fCarry = ((a_uResult) >> ((a_cBitsWidth) - 1)) & X86_EFL_CF; \
     2379        fEflTmp |= fCarry; \
     2380        fEflTmp |= (((a_uResult) >> ((a_cBitsWidth) - 2)) ^ fCarry) << X86_EFL_OF_BIT; \
     2381        *(a_pfEFlags) = fEflTmp; \
     2382    } while (0)
    23052383
    23062384IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     
    23092387    if (cShift)
    23102388    {
    2311         uint64_t uDst = *puDst;
    2312         uint64_t uResult;
     2389        uint64_t const uResult = ASMRotateRightU64(*puDst, cShift);
     2390        *puDst = uResult;
     2391        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROR(pfEFlags, uResult, 64);
     2392    }
     2393}
     2394
     2395# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2396
     2397IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u32,(uint32_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2398{
     2399    cShift &= 31;
     2400    if (cShift)
     2401    {
     2402        uint64_t const uResult = ASMRotateRightU32(*puDst, cShift);
     2403        *puDst = uResult;
     2404        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROR(pfEFlags, uResult, 32);
     2405    }
     2406}
     2407
     2408
     2409IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u16,(uint16_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2410{
     2411    cShift &= 15;
     2412    if (cShift)
     2413    {
     2414        uint16_t uDst = *puDst;
     2415        uint16_t uResult;
    23132416        uResult  = uDst >> cShift;
    2314         uResult |= uDst << (64 - cShift);
     2417        uResult |= uDst << (16 - cShift);
    23152418        *puDst = uResult;
    2316 
    2317         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2318            it the same way as for 1 bit shifts (OF = OF XOR New-CF). */
    2319         AssertCompile(X86_EFL_CF_BIT == 0);
    2320         uint32_t fEfl   = *pfEFlags & ~(X86_EFL_CF | X86_EFL_OF);
    2321         uint32_t fCarry = (uResult >> 63) & X86_EFL_CF;
    2322         fEfl |= fCarry;
    2323         fEfl |= (((uResult >> 62) ^ fCarry) << X86_EFL_OF_BIT) & X86_EFL_OF;
    2324         *pfEFlags = fEfl;
    2325     }
    2326 }
    2327 
    2328 
    2329 IEM_DECL_IMPL_DEF(void, iemAImpl_rcl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    2330 {
    2331     cShift &= 63;
     2419        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROR(pfEFlags, uResult, 16);
     2420    }
     2421}
     2422
     2423
     2424IEM_DECL_IMPL_DEF(void, iemAImpl_ror_u8,(uint8_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
     2425{
     2426    cShift &= 7;
    23322427    if (cShift)
    23332428    {
    2334         uint32_t fEfl = *pfEFlags;
    2335         uint64_t uDst = *puDst;
    2336         uint64_t uResult;
    2337         uResult = uDst << cShift;
    2338         AssertCompile(X86_EFL_CF_BIT == 0);
    2339         if (cShift > 1)
    2340             uResult |= uDst >> (65 - cShift);
    2341         uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (cShift - 1);
     2429        uint8_t uDst = *puDst;
     2430        uint8_t uResult;
     2431        uResult  = uDst >> cShift;
     2432        uResult |= uDst << (8 - cShift);
    23422433        *puDst = uResult;
    2343 
    2344         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2345            it the same way as for 1 bit shifts. */
    2346         uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF;
    2347         fEfl &= ~(X86_EFL_CF | X86_EFL_OF);
    2348         fEfl |= fCarry;
    2349         fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
    2350         *pfEFlags = fEfl;
    2351     }
    2352 }
    2353 
    2354 
    2355 IEM_DECL_IMPL_DEF(void, iemAImpl_rcr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    2356 {
    2357     cShift &= 63;
    2358     if (cShift)
    2359     {
    2360         uint32_t fEfl = *pfEFlags;
    2361         uint64_t uDst = *puDst;
    2362         uint64_t uResult;
    2363         uResult  = uDst >> cShift;
    2364         AssertCompile(X86_EFL_CF_BIT == 0);
    2365         if (cShift > 1)
    2366             uResult |= uDst << (65 - cShift);
    2367         uResult |= (uint64_t)(fEfl & X86_EFL_CF) << (64 - cShift);
    2368         *puDst = uResult;
    2369 
    2370         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2371            it the same way as for 1 bit shifts. */
    2372         uint32_t fCarry = (uDst >> (cShift - 1)) & X86_EFL_CF;
    2373         fEfl &= ~(X86_EFL_CF | X86_EFL_OF);
    2374         fEfl |= fCarry;
    2375         fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
    2376         *pfEFlags = fEfl;
    2377     }
    2378 }
    2379 
    2380 
    2381 IEM_DECL_IMPL_DEF(void, iemAImpl_shl_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    2382 {
    2383     cShift &= 63;
    2384     if (cShift)
    2385     {
    2386         uint64_t uDst = *puDst;
    2387         uint64_t uResult = uDst << cShift;
    2388         *puDst = uResult;
    2389 
    2390         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2391            it the same way as for 1 bit shifts.  The AF bit is undefined, we
    2392            always set it to zero atm. */
    2393         AssertCompile(X86_EFL_CF_BIT == 0);
    2394         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    2395         uint32_t fCarry = (uDst >> (64 - cShift)) & X86_EFL_CF;
    2396         fEfl |= fCarry;
    2397         fEfl |= ((uResult >> 63) ^ fCarry) << X86_EFL_OF_BIT;
    2398         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    2399         fEfl |= X86_EFL_CALC_ZF(uResult);
    2400         fEfl |= g_afParity[uResult & 0xff];
    2401         *pfEFlags = fEfl;
    2402     }
    2403 }
    2404 
    2405 
    2406 IEM_DECL_IMPL_DEF(void, iemAImpl_shr_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    2407 {
    2408     cShift &= 63;
    2409     if (cShift)
    2410     {
    2411         uint64_t uDst = *puDst;
    2412         uint64_t uResult = uDst >> cShift;
    2413         *puDst = uResult;
    2414 
    2415         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2416            it the same way as for 1 bit shifts.  The AF bit is undefined, we
    2417            always set it to zero atm. */
    2418         AssertCompile(X86_EFL_CF_BIT == 0);
    2419         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    2420         fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
    2421         fEfl |= (uDst >> 63) << X86_EFL_OF_BIT;
    2422         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    2423         fEfl |= X86_EFL_CALC_ZF(uResult);
    2424         fEfl |= g_afParity[uResult & 0xff];
    2425         *pfEFlags = fEfl;
    2426     }
    2427 }
    2428 
    2429 
    2430 IEM_DECL_IMPL_DEF(void, iemAImpl_sar_u64,(uint64_t *puDst, uint8_t cShift, uint32_t *pfEFlags))
    2431 {
    2432     cShift &= 63;
    2433     if (cShift)
    2434     {
    2435         uint64_t uDst = *puDst;
    2436         uint64_t uResult = (int64_t)uDst >> cShift;
    2437         *puDst = uResult;
    2438 
    2439         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2440            it the same way as for 1 bit shifts (0).  The AF bit is undefined,
    2441            we always set it to zero atm. */
    2442         AssertCompile(X86_EFL_CF_BIT == 0);
    2443         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    2444         fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
    2445         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    2446         fEfl |= X86_EFL_CALC_ZF(uResult);
    2447         fEfl |= g_afParity[uResult & 0xff];
    2448         *pfEFlags = fEfl;
    2449     }
    2450 }
    2451 
    2452 
    2453 IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags))
    2454 {
    2455     cShift &= 63;
    2456     if (cShift)
    2457     {
    2458         uint64_t uDst = *puDst;
    2459         uint64_t uResult;
    2460         uResult  = uDst << cShift;
    2461         uResult |= uSrc >> (64 - cShift);
    2462         *puDst = uResult;
    2463 
    2464         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2465            it the same way as for 1 bit shifts.  The AF bit is undefined,
    2466            we always set it to zero atm. */
    2467         AssertCompile(X86_EFL_CF_BIT == 0);
    2468         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    2469         fEfl |= (uDst >> (64 - cShift)) & X86_EFL_CF;
    2470         fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT;
    2471         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    2472         fEfl |= X86_EFL_CALC_ZF(uResult);
    2473         fEfl |= g_afParity[uResult & 0xff];
    2474         *pfEFlags = fEfl;
    2475     }
    2476 }
    2477 
    2478 
    2479 IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u64,(uint64_t *puDst, uint64_t uSrc, uint8_t cShift, uint32_t *pfEFlags))
    2480 {
    2481     cShift &= 63;
    2482     if (cShift)
    2483     {
    2484         uint64_t uDst = *puDst;
    2485         uint64_t uResult;
    2486         uResult  = uDst >> cShift;
    2487         uResult |= uSrc << (64 - cShift);
    2488         *puDst = uResult;
    2489 
    2490         /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement
    2491            it the same way as for 1 bit shifts.  The AF bit is undefined,
    2492            we always set it to zero atm. */
    2493         AssertCompile(X86_EFL_CF_BIT == 0);
    2494         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    2495         fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF;
    2496         fEfl |= (uint32_t)((uDst >> 63) ^ (uint32_t)(uResult >> 63)) << X86_EFL_OF_BIT;
    2497         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    2498         fEfl |= X86_EFL_CALC_ZF(uResult);
    2499         fEfl |= g_afParity[uResult & 0xff];
    2500         *pfEFlags = fEfl;
    2501     }
    2502 }
     2434        IEM_EFL_UPDATE_STATUS_BITS_FOR_ROR(pfEFlags, uResult, 8);
     2435    }
     2436}
     2437
     2438# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     2439
     2440
     2441/*
     2442 * RCL
     2443 */
     2444#define EMIT_RCL(a_cBitsWidth) \
     2445IEM_DECL_IMPL_DEF(void, iemAImpl_rcl_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, uint8_t cShift, uint32_t *pfEFlags)) \
     2446{ \
     2447    cShift &= a_cBitsWidth - 1; \
     2448    if (cShift) \
     2449    { \
     2450        uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
     2451        uint ## a_cBitsWidth ## _t       uResult = uDst << cShift; \
     2452        if (cShift > 1) \
     2453            uResult |= uDst >> (a_cBitsWidth + 1 - cShift); \
     2454        \
     2455        uint32_t fEfl = *pfEFlags; \
     2456        AssertCompile(X86_EFL_CF_BIT == 0); \
     2457        uResult |= (uint ## a_cBitsWidth ## _t)(fEfl & X86_EFL_CF) << (cShift - 1); \
     2458        \
     2459        *puDst = uResult; \
     2460        \
     2461        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2462           it the same way as for 1 bit shifts. */ \
     2463        fEfl &= ~(X86_EFL_CF | X86_EFL_OF); \
     2464        uint32_t const fCarry = (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; \
     2465        fEfl |= fCarry; \
     2466        fEfl |= ((uResult >> (a_cBitsWidth - 1)) ^ fCarry) << X86_EFL_OF_BIT; \
     2467        *pfEFlags = fEfl; \
     2468    } \
     2469}
     2470EMIT_RCL(64);
     2471# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2472EMIT_RCL(32);
     2473EMIT_RCL(16);
     2474EMIT_RCL(8);
     2475# endif
     2476
     2477
     2478/*
     2479 * RCR
     2480 */
     2481#define EMIT_RCR(a_cBitsWidth) \
     2482IEM_DECL_IMPL_DEF(void, iemAImpl_rcr_u ## a_cBitsWidth,(uint ## a_cBitsWidth ##_t *puDst, uint8_t cShift, uint32_t *pfEFlags)) \
     2483{ \
     2484    cShift &= a_cBitsWidth - 1; \
     2485    if (cShift) \
     2486    { \
     2487        uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
     2488        uint ## a_cBitsWidth ## _t       uResult = uDst >> cShift; \
     2489        if (cShift > 1) \
     2490            uResult |= uDst << (a_cBitsWidth + 1 - cShift); \
     2491        \
     2492        AssertCompile(X86_EFL_CF_BIT == 0); \
     2493        uint32_t fEfl = *pfEFlags; \
     2494        uResult |= (uint ## a_cBitsWidth ## _t)(fEfl & X86_EFL_CF) << (a_cBitsWidth - cShift); \
     2495        *puDst = uResult; \
     2496        \
     2497        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2498           it the same way as for 1 bit shifts. */ \
     2499        fEfl &= ~(X86_EFL_CF | X86_EFL_OF); \
     2500        uint32_t const fCarry = (uDst >> (cShift - 1)) & X86_EFL_CF; \
     2501        fEfl |= fCarry; \
     2502        fEfl |= ((uResult >> (a_cBitsWidth - 1)) ^ fCarry) << X86_EFL_OF_BIT; \
     2503        *pfEFlags = fEfl; \
     2504    } \
     2505}
     2506EMIT_RCR(64);
     2507# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2508EMIT_RCR(32);
     2509EMIT_RCR(16);
     2510EMIT_RCR(8);
     2511# endif
     2512
     2513
     2514/*
     2515 * SHL
     2516 */
     2517#define EMIT_SHL(a_cBitsWidth) \
     2518IEM_DECL_IMPL_DEF(void, iemAImpl_shl_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, uint8_t cShift, uint32_t *pfEFlags)) \
     2519{ \
     2520    cShift &= a_cBitsWidth - 1; \
     2521    if (cShift) \
     2522    { \
     2523        uint ## a_cBitsWidth ##_t const uDst  = *puDst; \
     2524        uint ## a_cBitsWidth ##_t       uResult = uDst << cShift; \
     2525        *puDst = uResult; \
     2526        \
     2527        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2528           it the same way as for 1 bit shifts.  The AF bit is undefined, we \
     2529           always set it to zero atm. */ \
     2530        AssertCompile(X86_EFL_CF_BIT == 0); \
     2531        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
     2532        uint32_t fCarry = (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; \
     2533        fEfl |= fCarry; \
     2534        fEfl |= ((uResult >> (a_cBitsWidth - 1)) ^ fCarry) << X86_EFL_OF_BIT; \
     2535        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
     2536        fEfl |= X86_EFL_CALC_ZF(uResult); \
     2537        fEfl |= g_afParity[uResult & 0xff]; \
     2538        *pfEFlags = fEfl; \
     2539    } \
     2540}
     2541EMIT_SHL(64)
     2542# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2543EMIT_SHL(32)
     2544EMIT_SHL(16)
     2545EMIT_SHL(8)
     2546# endif
     2547
     2548
     2549/*
     2550 * SHR
     2551 */
     2552#define EMIT_SHR(a_cBitsWidth) \
     2553IEM_DECL_IMPL_DEF(void, iemAImpl_shr_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, uint8_t cShift, uint32_t *pfEFlags)) \
     2554{ \
     2555    cShift &= a_cBitsWidth - 1; \
     2556    if (cShift) \
     2557    { \
     2558        uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
     2559        uint ## a_cBitsWidth ## _t       uResult = uDst >> cShift; \
     2560        *puDst = uResult; \
     2561        \
     2562        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2563           it the same way as for 1 bit shifts.  The AF bit is undefined, we \
     2564           always set it to zero atm. */ \
     2565        AssertCompile(X86_EFL_CF_BIT == 0); \
     2566        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
     2567        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; \
     2568        fEfl |= (uDst >> (a_cBitsWidth - 1)) << X86_EFL_OF_BIT; \
     2569        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
     2570        fEfl |= X86_EFL_CALC_ZF(uResult); \
     2571        fEfl |= g_afParity[uResult & 0xff]; \
     2572        *pfEFlags = fEfl; \
     2573    } \
     2574}
     2575EMIT_SHR(64)
     2576# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2577EMIT_SHR(32)
     2578EMIT_SHR(16)
     2579EMIT_SHR(8)
     2580# endif
     2581
     2582
     2583/*
     2584 * SAR
     2585 */
     2586#define EMIT_SAR(a_cBitsWidth) \
     2587IEM_DECL_IMPL_DEF(void, iemAImpl_sar_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, uint8_t cShift, uint32_t *pfEFlags)) \
     2588{ \
     2589    cShift &= a_cBitsWidth - 1; \
     2590    if (cShift) \
     2591    { \
     2592        uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
     2593        uint ## a_cBitsWidth ## _t       uResult = (int ## a_cBitsWidth ## _t)uDst >> cShift; \
     2594        *puDst = uResult; \
     2595        \
     2596        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2597           it the same way as for 1 bit shifts (0).  The AF bit is undefined, \
     2598           we always set it to zero atm. */ \
     2599        AssertCompile(X86_EFL_CF_BIT == 0); \
     2600        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
     2601        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; \
     2602        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
     2603        fEfl |= X86_EFL_CALC_ZF(uResult); \
     2604        fEfl |= g_afParity[uResult & 0xff]; \
     2605        *pfEFlags = fEfl; \
     2606    } \
     2607}
     2608EMIT_SAR(64)
     2609# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2610EMIT_SAR(32)
     2611EMIT_SAR(16)
     2612EMIT_SAR(8)
     2613# endif
     2614
     2615
     2616/*
     2617 * SHLD
     2618 */
     2619#define EMIT_SHLD(a_cBitsWidth) \
     2620IEM_DECL_IMPL_DEF(void, iemAImpl_shld_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, \
     2621                                                         uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, uint32_t *pfEFlags)) \
     2622{ \
     2623    cShift &= a_cBitsWidth - 1; \
     2624    if (cShift) \
     2625    { \
     2626        uint ## a_cBitsWidth ## _t const uDst = *puDst; \
     2627        uint ## a_cBitsWidth ## _t       uResult = uDst << cShift; \
     2628        uResult |= uSrc >> (a_cBitsWidth - cShift); \
     2629        *puDst = uResult; \
     2630        \
     2631        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2632           it the same way as for 1 bit shifts.  The AF bit is undefined, \
     2633           we always set it to zero atm. */ \
     2634        AssertCompile(X86_EFL_CF_BIT == 0); \
     2635        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
     2636        fEfl |= (uDst >> (a_cBitsWidth - cShift)) & X86_EFL_CF; \
     2637        fEfl |= (uint32_t)((uDst >> (a_cBitsWidth - 1)) ^ (uint32_t)(uResult >> (a_cBitsWidth - 1))) << X86_EFL_OF_BIT; \
     2638        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
     2639        fEfl |= X86_EFL_CALC_ZF(uResult); \
     2640        fEfl |= g_afParity[uResult & 0xff]; \
     2641        *pfEFlags = fEfl; \
     2642    } \
     2643}
     2644EMIT_SHLD(64)
     2645# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2646EMIT_SHLD(32)
     2647EMIT_SHLD(16)
     2648EMIT_SHLD(8)
     2649# endif
     2650
     2651
     2652/*
     2653 * SHRD
     2654 */
     2655#define EMIT_SHRD(a_cBitsWidth) \
     2656IEM_DECL_IMPL_DEF(void, iemAImpl_shrd_u ## a_cBitsWidth,(uint ## a_cBitsWidth ## _t *puDst, \
     2657                                                         uint ## a_cBitsWidth ## _t uSrc, uint8_t cShift, uint32_t *pfEFlags)) \
     2658{ \
     2659    cShift &= a_cBitsWidth - 1; \
     2660    if (cShift) \
     2661    { \
     2662        uint ## a_cBitsWidth ## _t const uDst    = *puDst; \
     2663        uint ## a_cBitsWidth ## _t       uResult = uDst >> cShift; \
     2664        uResult |= uSrc << (a_cBitsWidth - cShift); \
     2665        *puDst = uResult; \
     2666        \
     2667        /* Calc EFLAGS.  The OF bit is undefined if cShift > 1, we implement \
     2668           it the same way as for 1 bit shifts.  The AF bit is undefined, \
     2669           we always set it to zero atm. */ \
     2670        AssertCompile(X86_EFL_CF_BIT == 0); \
     2671        uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; \
     2672        fEfl |= (uDst >> (cShift - 1)) & X86_EFL_CF; \
     2673        fEfl |= (uint32_t)((uDst >> (a_cBitsWidth - 1)) ^ (uint32_t)(uResult >> (a_cBitsWidth - 1))) << X86_EFL_OF_BIT;  \
     2674        fEfl |= X86_EFL_CALC_SF(uResult, a_cBitsWidth); \
     2675        fEfl |= X86_EFL_CALC_ZF(uResult); \
     2676        fEfl |= g_afParity[uResult & 0xff]; \
     2677        *pfEFlags = fEfl; \
     2678    } \
     2679}
     2680EMIT_SHRD(64)
     2681# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     2682EMIT_SHRD(32)
     2683EMIT_SHRD(16)
     2684EMIT_SHRD(8)
     2685# endif
    25032686
    25042687
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