VirtualBox

Changeset 93756 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 15, 2022 3:08:15 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
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r93725 r93756  
    206206VBoxVMM_SOURCES.amd64 += \
    207207        VMMR3/PGMR3DbgA.asm \
    208         VMMAll/IEMAllAImpl.asm \
     208        $(if-expr !defined(IEM_WITHOUT_ASSEMBLY),VMMAll/IEMAllAImpl.asm,) \
    209209        VMMAll/VMMAllA.asm
    210210ifdef VBOX_WITH_VUSB
     
    511511        VMMAll/HMVMXAll.cpp \
    512512        VMMAll/IEMAll.cpp \
    513         VMMAll/IEMAllAImpl.asm \
     513        $(if-expr !defined(IEM_WITHOUT_ASSEMBLY),VMMAll/IEMAllAImpl.asm,) \
    514514        VMMAll/IEMAllAImplC.cpp \
    515515        VMMAll/IOMAll.cpp \
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r93744 r93756  
    2828
    2929/*********************************************************************************************************************************
     30*   Defined Constants And Macros                                                                                                 *
     31*********************************************************************************************************************************/
     32#if defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
     33# define IEM_WITHOUT_ASSEMBLY
     34#endif
     35
     36/**
     37 * Calculates the signed flag value given a result and it's bit width.
     38 *
     39 * The signed flag (SF) is a duplication of the most significant bit in the
     40 * result.
     41 *
     42 * @returns X86_EFL_SF or 0.
     43 * @param   a_uResult       Unsigned result value.
     44 * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
     45 */
     46#define X86_EFL_CALC_SF(a_uResult, a_cBitsWidth) \
     47    ( (uint32_t)((a_uResult) >> ((a_cBitsWidth) - X86_EFL_SF_BIT - 1)) & X86_EFL_SF )
     48
     49/**
     50 * Calculates the zero flag value given a result.
     51 *
     52 * The zero flag (ZF) indicates whether the result is zero or not.
     53 *
     54 * @returns X86_EFL_ZF or 0.
     55 * @param   a_uResult       Unsigned result value.
     56 */
     57#define X86_EFL_CALC_ZF(a_uResult) \
     58    ( (uint32_t)((a_uResult) == 0) << X86_EFL_ZF_BIT )
     59
     60/**
     61 * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after arithmetic op.
     62 *
     63 * CF and OF are defined to be 0 by logical operations.  AF on the other hand is
     64 * undefined.  We do not set AF, as that seems to make the most sense (which
     65 * probably makes it the most wrong in real life).
     66 *
     67 * @returns Status bits.
     68 * @param   a_pfEFlags      Pointer to the 32-bit EFLAGS value to update.
     69 * @param   a_uResult       Unsigned result value.
     70 * @param   a_uSrc          The source value (for AF calc).
     71 * @param   a_uDst          The original destination value (for AF calc).
     72 * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
     73 * @param   a_CfExpr        Bool expression for the carry flag (CF).
     74 * @param   a_OfMethod      0 for ADD-style, 1 for SUB-style.
     75 */
     76#define IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(a_pfEFlags, a_uResult, a_uDst, a_Src, a_cBitsWidth, a_CfExpr, a_OfMethod) \
     77    do { \
     78        uint32_t fEflTmp = *(a_pfEFlags); \
     79        fEflTmp &= ~X86_EFL_STATUS_BITS; \
     80        fEflTmp |= (a_CfExpr) << X86_EFL_CF_BIT; \
     81        fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     82        fEflTmp |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; \
     83        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
     84        fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \
     85        fEflTmp |= (   ((uDst ^ uSrc ^ (a_OfMethod == 0 ? RT_BIT_64(a_cBitsWidth - 1) : 0)) & (uResult ^ uDst))  \
     86                    >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; \
     87        *(a_pfEFlags) = fEflTmp; \
     88    } while (0)
     89
     90/**
     91 * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after a logical op.
     92 *
     93 * CF and OF are defined to be 0 by logical operations.  AF on the other hand is
     94 * undefined.  We do not set AF, as that seems to make the most sense (which
     95 * probably makes it the most wrong in real life).
     96 *
     97 * @returns Status bits.
     98 * @param   a_pfEFlags      Pointer to the 32-bit EFLAGS value to update.
     99 * @param   a_uResult       Unsigned result value.
     100 * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
     101 * @param   a_fExtra        Additional bits to set.
     102 */
     103#define IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(a_pfEFlags, a_uResult, a_cBitsWidth, a_fExtra) \
     104    do { \
     105        uint32_t fEflTmp = *(a_pfEFlags); \
     106        fEflTmp &= ~X86_EFL_STATUS_BITS; \
     107        fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
     108        fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
     109        fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \
     110        fEflTmp |= (a_fExtra); \
     111        *(a_pfEFlags) = fEflTmp; \
     112    } while (0)
     113
     114
     115/*********************************************************************************************************************************
    30116*   Global Variables                                                                                                             *
    31117*********************************************************************************************************************************/
    32 #ifndef RT_ARCH_AMD64
     118#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    33119/**
    34120 * Parity calculation table.
     
    326412    /* 0xff = 11111111b */ X86_EFL_PF,
    327413};
    328 #endif /* RT_ARCH_AMD64 */
    329 
    330 
    331 /**
    332  * Calculates the signed flag value given a result and it's bit width.
    333  *
    334  * The signed flag (SF) is a duplication of the most significant bit in the
    335  * result.
    336  *
    337  * @returns X86_EFL_SF or 0.
    338  * @param   a_uResult       Unsigned result value.
    339  * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
    340  */
    341 #define X86_EFL_CALC_SF(a_uResult, a_cBitsWidth) \
    342     ( (uint32_t)((a_uResult) >> ((a_cBitsWidth) - X86_EFL_SF_BIT - 1)) & X86_EFL_SF )
    343 
    344 /**
    345  * Calculates the zero flag value given a result.
    346  *
    347  * The zero flag (ZF) indicates whether the result is zero or not.
    348  *
    349  * @returns X86_EFL_ZF or 0.
    350  * @param   a_uResult       Unsigned result value.
    351  */
    352 #define X86_EFL_CALC_ZF(a_uResult) \
    353     ( (uint32_t)((a_uResult) == 0) << X86_EFL_ZF_BIT )
    354 
    355 /**
    356  * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after a logical op.
    357  *
    358  * CF and OF are defined to be 0 by logical operations.  AF on the other hand is
    359  * undefined.  We do not set AF, as that seems to make the most sense (which
    360  * probably makes it the most wrong in real life).
    361  *
    362  * @returns Status bits.
    363  * @param   a_pfEFlags      Pointer to the 32-bit EFLAGS value to update.
    364  * @param   a_uResult       Unsigned result value.
    365  * @param   a_cBitsWidth    The width of the result (8, 16, 32, 64).
    366  * @param   a_fExtra        Additional bits to set.
    367  */
    368 #define IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(a_pfEFlags, a_uResult, a_cBitsWidth, a_fExtra) \
    369     do { \
    370         uint32_t fEflTmp = *(a_pfEFlags); \
    371         fEflTmp &= ~X86_EFL_STATUS_BITS; \
    372         fEflTmp |= g_afParity[(a_uResult) & 0xff]; \
    373         fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \
    374         fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \
    375         fEflTmp |= (a_fExtra); \
    376         *(a_pfEFlags) = fEflTmp; \
    377     } while (0)
    378 
    379 
    380 #ifndef RT_ARCH_AMD64
     414#endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */
     415
     416
     417
     418#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    381419/*
    382420 * There are a few 64-bit on 32-bit things we'd rather do in C.  Actually, doing
     
    384422 */
    385423
    386 
    387 /* Binary ops */
     424/*********************************************************************************************************************************
     425*   Binary Operations                                                                                                            *
     426*********************************************************************************************************************************/
     427
     428/*
     429 * ADD
     430 */
    388431
    389432IEM_DECL_IMPL_DEF(void, iemAImpl_add_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    392435    uint64_t uResult = uDst + uSrc;
    393436    *puDst = uResult;
    394 
    395     /* Calc EFLAGS. */
    396     uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    397     fEfl |= (uResult < uDst) << X86_EFL_CF_BIT;
    398     fEfl |= g_afParity[uResult & 0xff];
    399     fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF;
    400     fEfl |= X86_EFL_CALC_ZF(uResult);
    401     fEfl |= X86_EFL_CALC_SF(uResult, 64);
    402     fEfl |= (((uDst ^ uSrc ^ RT_BIT_64(63)) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF;
    403     *pfEFlags = fEfl;
    404 }
    405 
     437    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult < uDst, 0);
     438}
     439
     440# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     441
     442IEM_DECL_IMPL_DEF(void, iemAImpl_add_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     443{
     444    uint32_t uDst    = *puDst;
     445    uint32_t uResult = uDst + uSrc;
     446    *puDst = uResult;
     447    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult < uDst, 0);
     448}
     449
     450
     451IEM_DECL_IMPL_DEF(void, iemAImpl_add_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     452{
     453    uint16_t uDst    = *puDst;
     454    uint16_t uResult = uDst + uSrc;
     455    *puDst = uResult;
     456    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult < uDst, 0);
     457}
     458
     459
     460IEM_DECL_IMPL_DEF(void, iemAImpl_add_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     461{
     462    uint8_t uDst    = *puDst;
     463    uint8_t uResult = uDst + uSrc;
     464    *puDst = uResult;
     465    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult < uDst, 0);
     466}
     467
     468# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     469
     470/*
     471 * ADC
     472 */
    406473
    407474IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    414481        uint64_t uResult = uDst + uSrc + 1;
    415482        *puDst = uResult;
    416 
    417         /* Calc EFLAGS. */
    418483        /** @todo verify AF and OF calculations. */
    419         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    420         fEfl |= (uResult <= uDst) << X86_EFL_CF_BIT;
    421         fEfl |= g_afParity[uResult & 0xff];
    422         fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF;
    423         fEfl |= X86_EFL_CALC_ZF(uResult);
    424         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    425         fEfl |= (((uDst ^ uSrc ^ RT_BIT_64(63)) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF;
    426         *pfEFlags = fEfl;
    427     }
    428 }
    429 
     484        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult <= uDst, 0);
     485    }
     486}
     487
     488# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     489
     490IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     491{
     492    if (!(*pfEFlags & X86_EFL_CF))
     493        iemAImpl_add_u32(puDst, uSrc, pfEFlags);
     494    else
     495    {
     496        uint32_t uDst    = *puDst;
     497        uint32_t uResult = uDst + uSrc + 1;
     498        *puDst = uResult;
     499        /** @todo verify AF and OF calculations. */
     500        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult <= uDst, 0);
     501    }
     502}
     503
     504
     505IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     506{
     507    if (!(*pfEFlags & X86_EFL_CF))
     508        iemAImpl_add_u16(puDst, uSrc, pfEFlags);
     509    else
     510    {
     511        uint16_t uDst    = *puDst;
     512        uint16_t uResult = uDst + uSrc + 1;
     513        *puDst = uResult;
     514        /** @todo verify AF and OF calculations. */
     515        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult <= uDst, 0);
     516    }
     517}
     518
     519
     520IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     521{
     522    if (!(*pfEFlags & X86_EFL_CF))
     523        iemAImpl_add_u8(puDst, uSrc, pfEFlags);
     524    else
     525    {
     526        uint8_t uDst    = *puDst;
     527        uint8_t uResult = uDst + uSrc + 1;
     528        *puDst = uResult;
     529        /** @todo verify AF and OF calculations. */
     530        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult <= uDst, 0);
     531    }
     532}
     533
     534# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     535
     536/*
     537 * SUB
     538 */
    430539
    431540IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    434543    uint64_t uResult = uDst - uSrc;
    435544    *puDst = uResult;
    436 
    437     /* Calc EFLAGS. */
    438     uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    439     fEfl |= (uDst < uSrc) << X86_EFL_CF_BIT;
    440     fEfl |= g_afParity[uResult & 0xff];
    441     fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF;
    442     fEfl |= X86_EFL_CALC_ZF(uResult);
    443     fEfl |= X86_EFL_CALC_SF(uResult, 64);
    444     fEfl |= (((uDst ^ uSrc) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF;
    445     *pfEFlags = fEfl;
    446 }
    447 
     545    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult < uDst, 1);
     546}
     547
     548# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     549
     550IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     551{
     552    uint32_t uDst    = *puDst;
     553    uint32_t uResult = uDst - uSrc;
     554    *puDst = uResult;
     555    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult < uDst, 1);
     556}
     557
     558
     559IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     560{
     561    uint16_t uDst    = *puDst;
     562    uint16_t uResult = uDst - uSrc;
     563    *puDst = uResult;
     564    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult < uDst, 1);
     565}
     566
     567
     568IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     569{
     570    uint8_t uDst    = *puDst;
     571    uint8_t uResult = uDst - uSrc;
     572    *puDst = uResult;
     573    IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult < uDst, 1);
     574}
     575
     576# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     577
     578/*
     579 * SBB
     580 */
    448581
    449582IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    456589        uint64_t uResult = uDst - uSrc - 1;
    457590        *puDst = uResult;
    458 
    459         /* Calc EFLAGS. */
    460591        /** @todo verify AF and OF calculations. */
    461         uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS;
    462         fEfl |= (uDst <= uSrc) << X86_EFL_CF_BIT;
    463         fEfl |= g_afParity[uResult & 0xff];
    464         fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF;
    465         fEfl |= X86_EFL_CALC_ZF(uResult);
    466         fEfl |= X86_EFL_CALC_SF(uResult, 64);
    467         fEfl |= (((uDst ^ uSrc) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF;
    468         *pfEFlags = fEfl;
    469     }
    470 }
    471 
     592        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult <= uDst, 1);
     593    }
     594}
     595
     596# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     597
     598IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     599{
     600    if (!(*pfEFlags & X86_EFL_CF))
     601        iemAImpl_sub_u32(puDst, uSrc, pfEFlags);
     602    else
     603    {
     604        uint32_t uDst    = *puDst;
     605        uint32_t uResult = uDst - uSrc - 1;
     606        *puDst = uResult;
     607        /** @todo verify AF and OF calculations. */
     608        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult <= uDst, 1);
     609    }
     610}
     611
     612
     613IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     614{
     615    if (!(*pfEFlags & X86_EFL_CF))
     616        iemAImpl_sub_u16(puDst, uSrc, pfEFlags);
     617    else
     618    {
     619        uint16_t uDst    = *puDst;
     620        uint16_t uResult = uDst - uSrc - 1;
     621        *puDst = uResult;
     622        /** @todo verify AF and OF calculations. */
     623        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult <= uDst, 1);
     624    }
     625}
     626
     627
     628IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     629{
     630    if (!(*pfEFlags & X86_EFL_CF))
     631        iemAImpl_sub_u8(puDst, uSrc, pfEFlags);
     632    else
     633    {
     634        uint8_t uDst    = *puDst;
     635        uint8_t uResult = uDst - uSrc - 1;
     636        *puDst = uResult;
     637        /** @todo verify AF and OF calculations. */
     638        IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult <= uDst, 1);
     639    }
     640}
     641
     642# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     643
     644
     645/*
     646 * OR
     647 */
    472648
    473649IEM_DECL_IMPL_DEF(void, iemAImpl_or_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    478654}
    479655
     656# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     657
     658IEM_DECL_IMPL_DEF(void, iemAImpl_or_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     659{
     660    uint32_t uResult = *puDst | uSrc;
     661    *puDst = uResult;
     662    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0);
     663}
     664
     665
     666IEM_DECL_IMPL_DEF(void, iemAImpl_or_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     667{
     668    uint16_t uResult = *puDst | uSrc;
     669    *puDst = uResult;
     670    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0);
     671}
     672
     673
     674IEM_DECL_IMPL_DEF(void, iemAImpl_or_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     675{
     676    uint8_t uResult = *puDst | uSrc;
     677    *puDst = uResult;
     678    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0);
     679}
     680
     681# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     682
     683/*
     684 * XOR
     685 */
    480686
    481687IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    486692}
    487693
     694# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     695
     696IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     697{
     698    uint32_t uResult = *puDst ^ uSrc;
     699    *puDst = uResult;
     700    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0);
     701}
     702
     703
     704IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     705{
     706    uint16_t uResult = *puDst ^ uSrc;
     707    *puDst = uResult;
     708    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0);
     709}
     710
     711
     712IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     713{
     714    uint8_t uResult = *puDst ^ uSrc;
     715    *puDst = uResult;
     716    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0);
     717}
     718
     719# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     720
     721/*
     722 * AND
     723 */
    488724
    489725IEM_DECL_IMPL_DEF(void, iemAImpl_and_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    494730}
    495731
     732# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     733
     734IEM_DECL_IMPL_DEF(void, iemAImpl_and_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     735{
     736    uint32_t uResult = *puDst & uSrc;
     737    *puDst = uResult;
     738    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0);
     739}
     740
     741
     742IEM_DECL_IMPL_DEF(void, iemAImpl_and_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     743{
     744    uint16_t uResult = *puDst & uSrc;
     745    *puDst = uResult;
     746    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0);
     747}
     748
     749
     750IEM_DECL_IMPL_DEF(void, iemAImpl_and_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     751{
     752    uint8_t uResult = *puDst & uSrc;
     753    *puDst = uResult;
     754    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0);
     755}
     756
     757# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     758
     759/*
     760 * CMP
     761 */
    496762
    497763IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    501767}
    502768
     769# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     770
     771IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     772{
     773    uint32_t uDstTmp = *puDst;
     774    iemAImpl_sub_u32(&uDstTmp, uSrc, pfEFlags);
     775}
     776
     777
     778IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     779{
     780    uint16_t uDstTmp = *puDst;
     781    iemAImpl_sub_u16(&uDstTmp, uSrc, pfEFlags);
     782}
     783
     784
     785IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     786{
     787    uint8_t uDstTmp = *puDst;
     788    iemAImpl_sub_u8(&uDstTmp, uSrc, pfEFlags);
     789}
     790
     791# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     792
     793/*
     794 * TEST
     795 */
    503796
    504797IEM_DECL_IMPL_DEF(void, iemAImpl_test_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    508801}
    509802
     803# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     804
     805IEM_DECL_IMPL_DEF(void, iemAImpl_test_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     806{
     807    uint32_t uResult = *puDst & uSrc;
     808    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0);
     809}
     810
     811
     812IEM_DECL_IMPL_DEF(void, iemAImpl_test_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     813{
     814    uint16_t uResult = *puDst & uSrc;
     815    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0);
     816}
     817
     818
     819IEM_DECL_IMPL_DEF(void, iemAImpl_test_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags))
     820{
     821    uint8_t uResult = *puDst & uSrc;
     822    IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0);
     823}
     824
     825# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     826
     827
     828/*
     829 * LOCK prefixed variants of the above
     830 */
    510831
    511832/** 64-bit locked binary operand operation. */
    512 # define DO_LOCKED_BIN_OP_U64(a_Mnemonic) \
     833# define DO_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth) \
    513834    do { \
    514         uint64_t uOld = ASMAtomicReadU64(puDst); \
    515         uint64_t uTmp; \
     835        uint ## a_cBitsWidth ## _t uOld = ASMAtomicUoReadU ## a_cBitsWidth(puDst); \
     836        uint ## a_cBitsWidth ## _t uTmp; \
    516837        uint32_t fEflTmp; \
    517838        do \
     
    519840            uTmp = uOld; \
    520841            fEflTmp = *pfEFlags; \
    521             iemAImpl_ ## a_Mnemonic ## _u64(&uTmp, uSrc, &fEflTmp); \
    522         } while (!ASMAtomicCmpXchgExU64(puDst, uTmp, uOld, &uOld)); \
     842            iemAImpl_ ## a_Mnemonic ## _u ## a_cBitsWidth(&uTmp, uSrc, &fEflTmp); \
     843        } while (!ASMAtomicCmpXchgExU ## a_cBitsWidth(puDst, uTmp, uOld, &uOld)); \
    523844        *pfEFlags = fEflTmp; \
    524845    } while (0)
    525846
    526847
    527 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    528 {
    529     DO_LOCKED_BIN_OP_U64(add);
    530 }
    531 
    532 
    533 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    534 {
    535     DO_LOCKED_BIN_OP_U64(adc);
    536 }
    537 
    538 
    539 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    540 {
    541     DO_LOCKED_BIN_OP_U64(sub);
    542 }
    543 
    544 
    545 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    546 {
    547     DO_LOCKED_BIN_OP_U64(sbb);
    548 }
    549 
    550 
    551 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    552 {
    553     DO_LOCKED_BIN_OP_U64(or);
    554 }
    555 
    556 
    557 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    558 {
    559     DO_LOCKED_BIN_OP_U64(xor);
    560 }
    561 
    562 
    563 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    564 {
    565     DO_LOCKED_BIN_OP_U64(and);
    566 }
    567 
    568 
    569 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags))
    570 {
    571     uint64_t uDst    = *puDst;
    572     uint64_t uResult = uDst;
    573     iemAImpl_add_u64(&uResult, *puReg, pfEFlags);
    574     *puDst = uResult;
    575     *puReg = uDst;
    576 }
    577 
    578 
    579 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags))
    580 {
    581     uint64_t uOld = ASMAtomicReadU64(puDst);
    582     uint64_t uTmpDst;
    583     uint32_t fEflTmp;
    584     do
    585     {
    586         uTmpDst = uOld;
    587         fEflTmp = *pfEFlags;
    588         iemAImpl_add_u64(&uTmpDst, *puReg, pfEFlags);
    589     } while (!ASMAtomicCmpXchgExU64(puDst, uTmpDst, uOld, &uOld));
    590     *puReg    = uOld;
    591     *pfEFlags = fEflTmp;
    592 }
    593 
    594 
    595 /* Bit operations (same signature as above). */
     848#define EMIT_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth) \
     849    IEM_DECL_IMPL_DEF(void, iemAImpl_ ## a_Mnemonic ## _u ## a_cBitsWidth ##  _locked,(uint ## a_cBitsWidth ## _t *puDst, \
     850                                                                                       uint ## a_cBitsWidth ## _t uSrc, \
     851                                                                                       uint32_t *pfEFlags)) \
     852    { \
     853        DO_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth); \
     854    }
     855
     856EMIT_LOCKED_BIN_OP(add, 64)
     857EMIT_LOCKED_BIN_OP(adc, 64)
     858EMIT_LOCKED_BIN_OP(sub, 64)
     859EMIT_LOCKED_BIN_OP(sbb, 64)
     860EMIT_LOCKED_BIN_OP(or,  64)
     861EMIT_LOCKED_BIN_OP(xor, 64)
     862EMIT_LOCKED_BIN_OP(and, 64)
     863# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     864EMIT_LOCKED_BIN_OP(add, 32)
     865EMIT_LOCKED_BIN_OP(adc, 32)
     866EMIT_LOCKED_BIN_OP(sub, 32)
     867EMIT_LOCKED_BIN_OP(sbb, 32)
     868EMIT_LOCKED_BIN_OP(or,  32)
     869EMIT_LOCKED_BIN_OP(xor, 32)
     870EMIT_LOCKED_BIN_OP(and, 32)
     871
     872EMIT_LOCKED_BIN_OP(add, 16)
     873EMIT_LOCKED_BIN_OP(adc, 16)
     874EMIT_LOCKED_BIN_OP(sub, 16)
     875EMIT_LOCKED_BIN_OP(sbb, 16)
     876EMIT_LOCKED_BIN_OP(or,  16)
     877EMIT_LOCKED_BIN_OP(xor, 16)
     878EMIT_LOCKED_BIN_OP(and, 16)
     879
     880EMIT_LOCKED_BIN_OP(add, 8)
     881EMIT_LOCKED_BIN_OP(adc, 8)
     882EMIT_LOCKED_BIN_OP(sub, 8)
     883EMIT_LOCKED_BIN_OP(sbb, 8)
     884EMIT_LOCKED_BIN_OP(or,  8)
     885EMIT_LOCKED_BIN_OP(xor, 8)
     886EMIT_LOCKED_BIN_OP(and, 8)
     887# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     888
     889
     890/*
     891 * Bit operations (same signature as above).
     892 */
     893
     894/*
     895 * BT
     896 */
    596897
    597898IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    607908}
    608909
     910# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     911
     912IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     913{
     914    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     915       logical operation (AND/OR/whatever). */
     916    Assert(uSrc < 32);
     917    uint32_t uDst = *puDst;
     918    if (uDst & RT_BIT_32(uSrc))
     919        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF);
     920    else
     921        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0);
     922}
     923
     924IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     925{
     926    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     927       logical operation (AND/OR/whatever). */
     928    Assert(uSrc < 16);
     929    uint16_t uDst = *puDst;
     930    if (uDst & RT_BIT_32(uSrc))
     931        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF);
     932    else
     933        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0);
     934}
     935
     936# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     937
     938/*
     939 * BTC
     940 */
     941
    609942IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    610943{
     
    628961}
    629962
     963# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     964
     965IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     966{
     967    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     968       logical operation (AND/OR/whatever). */
     969    Assert(uSrc < 32);
     970    uint32_t fMask = RT_BIT_32(uSrc);
     971    uint32_t uDst = *puDst;
     972    if (uDst & fMask)
     973    {
     974        uDst &= ~fMask;
     975        *puDst = uDst;
     976        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF);
     977    }
     978    else
     979    {
     980        uDst |= fMask;
     981        *puDst = uDst;
     982        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0);
     983    }
     984}
     985
     986
     987IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     988{
     989    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     990       logical operation (AND/OR/whatever). */
     991    Assert(uSrc < 16);
     992    uint16_t fMask = RT_BIT_32(uSrc);
     993    uint16_t uDst = *puDst;
     994    if (uDst & fMask)
     995    {
     996        uDst &= ~fMask;
     997        *puDst = uDst;
     998        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF);
     999    }
     1000    else
     1001    {
     1002        uDst |= fMask;
     1003        *puDst = uDst;
     1004        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0);
     1005    }
     1006}
     1007
     1008# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     1009
     1010/*
     1011 * BTR
     1012 */
     1013
    6301014IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    6311015{
     
    6441028        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 64, 0);
    6451029}
     1030
     1031# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1032
     1033IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1034{
     1035    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     1036       logical operation (AND/OR/whatever). */
     1037    Assert(uSrc < 32);
     1038    uint32_t fMask = RT_BIT_32(uSrc);
     1039    uint32_t uDst = *puDst;
     1040    if (uDst & fMask)
     1041    {
     1042        uDst &= ~fMask;
     1043        *puDst = uDst;
     1044        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF);
     1045    }
     1046    else
     1047        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0);
     1048}
     1049
     1050
     1051IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1052{
     1053    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     1054       logical operation (AND/OR/whatever). */
     1055    Assert(uSrc < 16);
     1056    uint16_t fMask = RT_BIT_32(uSrc);
     1057    uint16_t uDst = *puDst;
     1058    if (uDst & fMask)
     1059    {
     1060        uDst &= ~fMask;
     1061        *puDst = uDst;
     1062        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF);
     1063    }
     1064    else
     1065        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0);
     1066}
     1067
     1068# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     1069
     1070/*
     1071 * BTS
     1072 */
    6461073
    6471074IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
     
    6621089}
    6631090
    664 
    665 IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    666 {
    667     DO_LOCKED_BIN_OP_U64(btc);
    668 }
    669 
    670 IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    671 {
    672     DO_LOCKED_BIN_OP_U64(btr);
    673 }
    674 
    675 IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags))
    676 {
    677     DO_LOCKED_BIN_OP_U64(bts);
    678 }
     1091# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1092
     1093IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags))
     1094{
     1095    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     1096       logical operation (AND/OR/whatever). */
     1097    Assert(uSrc < 32);
     1098    uint32_t fMask = RT_BIT_32(uSrc);
     1099    uint32_t uDst = *puDst;
     1100    if (uDst & fMask)
     1101        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF);
     1102    else
     1103    {
     1104        uDst |= fMask;
     1105        *puDst = uDst;
     1106        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0);
     1107    }
     1108}
     1109
     1110
     1111IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags))
     1112{
     1113    /* Note! "undefined" flags: OF, SF, ZF, AF, PF.  We set them as after an
     1114       logical operation (AND/OR/whatever). */
     1115    Assert(uSrc < 16);
     1116    uint16_t fMask = RT_BIT_32(uSrc);
     1117    uint32_t uDst = *puDst;
     1118    if (uDst & fMask)
     1119        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF);
     1120    else
     1121    {
     1122        uDst |= fMask;
     1123        *puDst = uDst;
     1124        IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0);
     1125    }
     1126}
     1127
     1128# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
     1129
     1130
     1131EMIT_LOCKED_BIN_OP(btc, 64)
     1132EMIT_LOCKED_BIN_OP(btr, 64)
     1133EMIT_LOCKED_BIN_OP(bts, 64)
     1134# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1135EMIT_LOCKED_BIN_OP(btc, 32)
     1136EMIT_LOCKED_BIN_OP(btr, 32)
     1137EMIT_LOCKED_BIN_OP(bts, 32)
     1138
     1139EMIT_LOCKED_BIN_OP(btc, 16)
     1140EMIT_LOCKED_BIN_OP(btr, 16)
     1141EMIT_LOCKED_BIN_OP(bts, 16)
     1142# endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */
    6791143
    6801144
     
    11321596
    11331597
    1134 #endif /* !RT_ARCH_AMD64 */
    1135 #ifndef RT_ARCH_AMD64
     1598/*
     1599 * XADD and LOCK XADD.
     1600 */
     1601
     1602IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags))
     1603{
     1604    uint64_t uDst    = *puDst;
     1605    uint64_t uResult = uDst;
     1606    iemAImpl_add_u64(&uResult, *puReg, pfEFlags);
     1607    *puDst = uResult;
     1608    *puReg = uDst;
     1609}
     1610
     1611
     1612IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags))
     1613{
     1614    uint64_t uOld = ASMAtomicUoReadU64(puDst);
     1615    uint64_t uTmpDst;
     1616    uint32_t fEflTmp;
     1617    do
     1618    {
     1619        uTmpDst = uOld;
     1620        fEflTmp = *pfEFlags;
     1621        iemAImpl_add_u64(&uTmpDst, *puReg, pfEFlags);
     1622    } while (!ASMAtomicCmpXchgExU64(puDst, uTmpDst, uOld, &uOld));
     1623    *puReg    = uOld;
     1624    *pfEFlags = fEflTmp;
     1625}
     1626
     1627# if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY)
     1628
     1629IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *puDst, uint32_t *puReg, uint32_t *pfEFlags))
     1630{
     1631    uint32_t uDst    = *puDst;
     1632    uint32_t uResult = uDst;
     1633    iemAImpl_add_u32(&uResult, *puReg, pfEFlags);
     1634    *puDst = uResult;
     1635    *puReg = uDst;
     1636}
     1637
     1638
     1639IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *puDst, uint32_t *puReg, uint32_t *pfEFlags))
     1640{
     1641    uint32_t uOld = ASMAtomicUoReadU32(puDst);
     1642    uint32_t uTmpDst;
     1643    uint32_t fEflTmp;
     1644    do
     1645    {
     1646        uTmpDst = uOld;
     1647        fEflTmp = *pfEFlags;
     1648        iemAImpl_add_u32(&uTmpDst, *puReg, pfEFlags);
     1649    } while (!ASMAtomicCmpXchgExU32(puDst, uTmpDst, uOld, &uOld));
     1650    *puReg    = uOld;
     1651    *pfEFlags = fEflTmp;
     1652}
     1653
     1654
     1655IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *puDst, uint16_t *puReg, uint32_t *pfEFlags))
     1656{
     1657    uint16_t uDst    = *puDst;
     1658    uint16_t uResult = uDst;
     1659    iemAImpl_add_u16(&uResult, *puReg, pfEFlags);
     1660    *puDst = uResult;
     1661    *puReg = uDst;
     1662}
     1663
     1664
     1665IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *puDst, uint16_t *puReg, uint32_t *pfEFlags))
     1666{
     1667    uint16_t uOld = ASMAtomicUoReadU16(puDst);
     1668    uint16_t uTmpDst;
     1669    uint32_t fEflTmp;
     1670    do
     1671    {
     1672        uTmpDst = uOld;
     1673        fEflTmp = *pfEFlags;
     1674        iemAImpl_add_u16(&uTmpDst, *puReg, pfEFlags);
     1675    } while (!ASMAtomicCmpXchgExU16(puDst, uTmpDst, uOld, &uOld));
     1676    *puReg    = uOld;
     1677    *pfEFlags = fEflTmp;
     1678}
     1679
     1680
     1681IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8,(uint8_t *puDst, uint8_t *puReg, uint32_t *pfEFlags))
     1682{
     1683    uint8_t uDst    = *puDst;
     1684    uint8_t uResult = uDst;
     1685    iemAImpl_add_u8(&uResult, *puReg, pfEFlags);
     1686    *puDst = uResult;
     1687    *puReg = uDst;
     1688}
     1689
     1690
     1691IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked,(uint8_t *puDst, uint8_t *puReg, uint32_t *pfEFlags))
     1692{
     1693    uint8_t uOld = ASMAtomicUoReadU8(puDst);
     1694    uint8_t uTmpDst;
     1695    uint32_t fEflTmp;
     1696    do
     1697    {
     1698        uTmpDst = uOld;
     1699        fEflTmp = *pfEFlags;
     1700        iemAImpl_add_u8(&uTmpDst, *puReg, pfEFlags);
     1701    } while (!ASMAtomicCmpXchgExU8(puDst, uTmpDst, uOld, &uOld));
     1702    *puReg    = uOld;
     1703    *pfEFlags = fEflTmp;
     1704}
     1705
     1706# endif
     1707
     1708
     1709#endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */
     1710#if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY)
    11361711
    11371712/* multiplication and division */
     
    13371912
    13381913
    1339 #endif /* !RT_ARCH_AMD64 */
     1914#endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */
    13401915
    13411916
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