VirtualBox

Changeset 87191 in vbox


Ignore:
Timestamp:
Jan 7, 2021 7:59:09 PM (4 years ago)
Author:
vboxsync
Message:

iprt/asm.h: More fun. Adding Xor and extended And, Or and Xor variants that returns the old value so ASM[Atomic]BitTestAnd[Set|Clear|Toggle] can more easily be implemented on non-x86 systems. bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm.h

    r87189 r87191  
    6363# pragma intrinsic(_InterlockedAnd)
    6464# pragma intrinsic(_InterlockedOr)
     65# pragma intrinsic(_InterlockedXor)
    6566# pragma intrinsic(_InterlockedIncrement)
    6667# pragma intrinsic(_InterlockedDecrement)
     
    41894190
    41904191/**
     4192 * Atomically OR an unsigned 32-bit value, ordered, extended version (for bitmap
     4193 * fallback).
     4194 *
     4195 * @returns Old value.
     4196 * @param   pu32   Pointer to the variable to OR @a u32 with.
     4197 * @param   u32    The value to OR @a *pu32 with.
     4198 */
     4199DECLINLINE(uint32_t) ASMAtomicOrExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4200{
     4201#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4202    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicOrEx32, pu32, DMB_SY,
     4203                                           "orr %w[uNew], %w[uOld], %w[uVal]\n\t",
     4204                                           "orr %[uNew], %[uOld], %[uVal]\n\t",
     4205                                           [uVal] "r" (u32));
     4206    return u32OldRet;
     4207
     4208#else
     4209    uint32_t u32RetOld = ASMAtomicUoReadU32(pu32);
     4210    uint32_t u32New;
     4211    do
     4212        u32New = u32RetOld | u32;
     4213    while (!ASMAtomicCmpXchgExU32(pu32, u32New, u32RetOld, &u32RetOld));
     4214    return u32RetOld;
     4215#endif
     4216}
     4217
     4218
     4219/**
    41914220 * Atomically Or a signed 32-bit value, ordered.
    41924221 *
     
    43124341
    43134342/**
     4343 * Atomically AND an unsigned 32-bit value, ordered, extended version.
     4344 *
     4345 * @returns Old value.
     4346 * @param   pu32   Pointer to the variable to AND @a u32 with.
     4347 * @param   u32    The value to AND @a *pu32 with.
     4348 */
     4349DECLINLINE(uint32_t) ASMAtomicAndExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4350{
     4351#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4352    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicAndEx32, pu32, DMB_SY,
     4353                                           "and %w[uNew], %w[uOld], %w[uVal]\n\t",
     4354                                           "and %[uNew], %[uOld], %[uVal]\n\t",
     4355                                           [uVal] "r" (u32));
     4356    return u32OldRet;
     4357
     4358#else
     4359    uint32_t u32RetOld = ASMAtomicUoReadU32(pu32);
     4360    uint32_t u32New;
     4361    do
     4362        u32New = u32RetOld & u32;
     4363    while (!ASMAtomicCmpXchgExU32(pu32, u32New, u32RetOld, &u32RetOld));
     4364    return u32RetOld;
     4365#endif
     4366}
     4367
     4368
     4369/**
    43144370 * Atomically And a signed 32-bit value, ordered.
    43154371 *
     
    43814437{
    43824438    ASMAtomicAndU64((uint64_t volatile RT_FAR *)pi64, (uint64_t)i64);
     4439}
     4440
     4441
     4442/**
     4443 * Atomically XOR an unsigned 32-bit value and a memory location, ordered.
     4444 *
     4445 * @param   pu32   Pointer to the variable to XOR @a u32 with.
     4446 * @param   u32    The value to XOR @a *pu32 with.
     4447 *
     4448 * @remarks x86: Requires a 386 or later.
     4449 */
     4450#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
     4451RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicXorU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
     4452#else
     4453DECLINLINE(void) ASMAtomicXorU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4454{
     4455# if RT_INLINE_ASM_USES_INTRIN
     4456    _InterlockedXor((long volatile RT_FAR *)pu32, u32);
     4457
     4458# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4459#  if RT_INLINE_ASM_GNU_STYLE
     4460    __asm__ __volatile__("lock; xor %1, %0\n\t"
     4461                         : "=m" (*pu32)
     4462                         : "ir" (u32)
     4463                         , "m" (*pu32)
     4464                         : "cc");
     4465#  else
     4466    __asm
     4467    {
     4468        mov     eax, [u32]
     4469#   ifdef RT_ARCH_AMD64
     4470        mov     rdx, [pu32]
     4471        lock xor [rdx], eax
     4472#   else
     4473        mov     edx, [pu32]
     4474        lock xor [edx], eax
     4475#   endif
     4476    }
     4477#  endif
     4478
     4479# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4480    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicXor32, pu32, DMB_SY,
     4481                                           "eor %w[uNew], %w[uNew], %w[uVal]\n\t",
     4482                                           "eor %[uNew], %[uNew], %[uVal]\n\t",
     4483                                           [uVal] "r" (u32));
     4484
     4485# else
     4486#  error "Port me"
     4487# endif
     4488}
     4489#endif
     4490
     4491
     4492/**
     4493 * Atomically XOR an unsigned 32-bit value and a memory location, ordered,
     4494 * extended version (for bitmaps).
     4495 *
     4496 * @returns Old value.
     4497 * @param   pu32   Pointer to the variable to XOR @a u32 with.
     4498 * @param   u32    The value to XOR @a *pu32 with.
     4499 */
     4500DECLINLINE(uint32_t) ASMAtomicXorExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4501{
     4502#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4503    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicXorEx32, pu32, DMB_SY,
     4504                                           "eor %w[uNew], %w[uOld], %w[uVal]\n\t",
     4505                                           "eor %[uNew], %[uOld], %[uVal]\n\t",
     4506                                           [uVal] "r" (u32));
     4507    return u32OldRet;
     4508
     4509#else
     4510    uint32_t u32RetOld = ASMAtomicUoReadU32(pu32);
     4511    uint32_t u32New;
     4512    do
     4513        u32New = u32RetOld ^ u32;
     4514    while (!ASMAtomicCmpXchgExU32(pu32, u32New, u32RetOld, &u32RetOld));
     4515    return u32RetOld;
     4516#endif
     4517}
     4518
     4519
     4520/**
     4521 * Atomically XOR a signed 32-bit value, ordered.
     4522 *
     4523 * @param   pi32   Pointer to the variable to XOR i32 with.
     4524 * @param   i32    The value to XOR *pi32 with.
     4525 *
     4526 * @remarks x86: Requires a 386 or later.
     4527 */
     4528DECLINLINE(void) ASMAtomicXorS32(int32_t volatile RT_FAR *pi32, int32_t i32) RT_NOTHROW_DEF
     4529{
     4530    ASMAtomicXorU32((uint32_t volatile RT_FAR *)pi32, (uint32_t)i32);
    43834531}
    43844532
     
    44324580
    44334581/**
     4582 * Atomically OR an unsigned 32-bit value, unordered but interrupt safe,
     4583 * extended version (for bitmap fallback).
     4584 *
     4585 * @returns Old value.
     4586 * @param   pu32   Pointer to the variable to OR @a u32 with.
     4587 * @param   u32    The value to OR @a *pu32 with.
     4588 */
     4589DECLINLINE(uint32_t) ASMAtomicUoOrExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4590{
     4591#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4592    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicUoOrExU32, pu32, NO_BARRIER,
     4593                                           "orr %w[uNew], %w[uOld], %w[uVal]\n\t",
     4594                                           "orr %[uNew], %[uOld], %[uVal]\n\t",
     4595                                           [uVal] "r" (u32));
     4596    return u32OldRet;
     4597
     4598#else
     4599    return ASMAtomicOrExU32(pu32, u32); /* (we have no unordered cmpxchg primitive atm.) */
     4600#endif
     4601}
     4602
     4603
     4604/**
    44344605 * Atomically OR a signed 32-bit value, unordered.
    44354606 *
     
    45494720
    45504721/**
     4722 * Atomically AND an unsigned 32-bit value, unordered, extended version (for
     4723 * bitmap fallback).
     4724 *
     4725 * @returns Old value.
     4726 * @param   pu32   Pointer to the pointer to AND @a u32 with.
     4727 * @param   u32    The value to AND @a *pu32 with.
     4728 */
     4729DECLINLINE(uint32_t) ASMAtomicUoAndExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4730{
     4731#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4732    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicUoAndEx32, pu32, NO_BARRIER,
     4733                                           "and %w[uNew], %w[uOld], %w[uVal]\n\t",
     4734                                           "and %[uNew], %[uOld], %[uVal]\n\t",
     4735                                           [uVal] "r" (u32));
     4736    return u32OldRet;
     4737
     4738#else
     4739    return ASMAtomicAndExU32(pu32, u32); /* (we have no unordered cmpxchg primitive atm.) */
     4740#endif
     4741}
     4742
     4743
     4744/**
    45514745 * Atomically And a signed 32-bit value, unordered.
    45524746 *
     
    46154809{
    46164810    ASMAtomicUoAndU64((uint64_t volatile RT_FAR *)pi64, (uint64_t)i64);
     4811}
     4812
     4813
     4814/**
     4815 * Atomically XOR an unsigned 32-bit value, unordered but interrupt safe.
     4816 *
     4817 * @param   pu32   Pointer to the variable to XOR @a u32 with.
     4818 * @param   u32    The value to OR @a *pu32 with.
     4819 *
     4820 * @remarks x86: Requires a 386 or later.
     4821 */
     4822#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
     4823RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicUoXorU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
     4824#else
     4825DECLINLINE(void) ASMAtomicUoXorU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4826{
     4827# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4828#  if RT_INLINE_ASM_GNU_STYLE
     4829    __asm__ __volatile__("xorl %1, %0\n\t"
     4830                         : "=m" (*pu32)
     4831                         : "ir" (u32)
     4832                         , "m" (*pu32)
     4833                         : "cc");
     4834#  else
     4835    __asm
     4836    {
     4837        mov     eax, [u32]
     4838#   ifdef RT_ARCH_AMD64
     4839        mov     rdx, [pu32]
     4840        xor     [rdx], eax
     4841#   else
     4842        mov     edx, [pu32]
     4843        xor     [edx], eax
     4844#   endif
     4845    }
     4846#  endif
     4847
     4848# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4849    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicUoXorU32, pu32, NO_BARRIER,
     4850                                           "eor %w[uNew], %w[uNew], %w[uVal]\n\t",
     4851                                           "eor %[uNew], %[uNew], %[uVal]\n\t",
     4852                                           [uVal] "r" (u32));
     4853
     4854# else
     4855#  error "Port me"
     4856# endif
     4857}
     4858#endif
     4859
     4860
     4861/**
     4862 * Atomically XOR an unsigned 32-bit value, unordered but interrupt safe,
     4863 * extended version (for bitmap fallback).
     4864 *
     4865 * @returns Old value.
     4866 * @param   pu32   Pointer to the variable to XOR @a u32 with.
     4867 * @param   u32    The value to OR @a *pu32 with.
     4868 */
     4869DECLINLINE(uint32_t) ASMAtomicUoXorExU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
     4870{
     4871#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4872    RTASM_ARM_LOAD_MODIFY_STORE_RET_OLD_32(ASMAtomicUoXorExU32, pu32, NO_BARRIER,
     4873                                           "eor %w[uNew], %w[uOld], %w[uVal]\n\t",
     4874                                           "eor %[uNew], %[uOld], %[uVal]\n\t",
     4875                                           [uVal] "r" (u32));
     4876    return u32OldRet;
     4877
     4878#else
     4879    return ASMAtomicXorExU32(pu32, u32); /* (we have no unordered cmpxchg primitive atm.) */
     4880#endif
     4881}
     4882
     4883
     4884/**
     4885 * Atomically XOR a signed 32-bit value, unordered.
     4886 *
     4887 * @param   pi32   Pointer to the variable to XOR @a u32 with.
     4888 * @param   i32    The value to XOR @a *pu32 with.
     4889 *
     4890 * @remarks x86: Requires a 386 or later.
     4891 */
     4892DECLINLINE(void) ASMAtomicUoXorS32(int32_t volatile RT_FAR *pi32, int32_t i32) RT_NOTHROW_DEF
     4893{
     4894    ASMAtomicUoXorU32((uint32_t volatile RT_FAR *)pi32, (uint32_t)i32);
    46174895}
    46184896
     
    53785656 *          traps accessing the last bits in the bitmap.
    53795657 */
    5380 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5658#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    53815659RT_ASM_DECL_PRAGMA_WATCOM(void) ASMBitToggle(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    53825660#else
     
    53855663# if RT_INLINE_ASM_USES_INTRIN
    53865664    _bittestandcomplement((long RT_FAR *)pvBitmap, iBit);
    5387 # elif RT_INLINE_ASM_GNU_STYLE
     5665# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5666#  if RT_INLINE_ASM_GNU_STYLE
    53885667    __asm__ __volatile__("btcl %1, %0"
    53895668                         : "=m" (*(volatile long *)pvBitmap)
     
    53925671                         : "memory"
    53935672                         , "cc");
    5394 # else
     5673#  else
    53955674    __asm
    53965675    {
    5397 ifdef RT_ARCH_AMD64
     5676 ifdef RT_ARCH_AMD64
    53985677        mov     rax, [pvBitmap]
    53995678        mov     edx, [iBit]
    54005679        btc     [rax], edx
    5401 else
     5680 else
    54025681        mov     eax, [pvBitmap]
    54035682        mov     edx, [iBit]
    54045683        btc     [eax], edx
    5405 endif
     5684 endif
    54065685    }
     5686#  endif
     5687# else
     5688    int32_t offBitmap = iBit / 32;
     5689    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
     5690    ASMAtomicUoXorU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31));
    54075691# endif
    54085692}
     
    54195703 * @remarks x86: Requires a 386 or later.
    54205704 */
    5421 #if RT_INLINE_ASM_EXTERNAL
     5705#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    54225706RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicBitToggle(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    54235707#else
     
    54255709{
    54265710    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
    5427 # if RT_INLINE_ASM_GNU_STYLE
     5711# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5712#  if RT_INLINE_ASM_GNU_STYLE
    54285713    __asm__ __volatile__("lock; btcl %1, %0"
    54295714                         : "=m" (*(volatile long RT_FAR *)pvBitmap)
     
    54325717                         : "memory"
    54335718                         , "cc");
    5434 # else
     5719#  else
    54355720    __asm
    54365721    {
    5437 ifdef RT_ARCH_AMD64
     5722 ifdef RT_ARCH_AMD64
    54385723        mov     rax, [pvBitmap]
    54395724        mov     edx, [iBit]
    54405725        lock btc [rax], edx
    5441 else
     5726 else
    54425727        mov     eax, [pvBitmap]
    54435728        mov     edx, [iBit]
    54445729        lock btc [eax], edx
    5445 endif
     5730 endif
    54465731    }
     5732#  endif
     5733# else
     5734    ASMAtomicXorU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31));
    54475735# endif
    54485736}
     
    54635751 *          traps accessing the last bits in the bitmap.
    54645752 */
    5465 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5753#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    54665754RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMBitTestAndSet(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    54675755#else
     
    54725760    rc.u8 = _bittestandset((long RT_FAR *)pvBitmap, iBit);
    54735761
    5474 # elif RT_INLINE_ASM_GNU_STYLE
     5762# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5763#  if RT_INLINE_ASM_GNU_STYLE
    54755764    __asm__ __volatile__("btsl %2, %1\n\t"
    54765765                         "setc %b0\n\t"
     
    54825771                         : "memory"
    54835772                         , "cc");
    5484 # else
     5773#  else
    54855774    __asm
    54865775    {
    54875776        mov     edx, [iBit]
    5488 ifdef RT_ARCH_AMD64
     5777 ifdef RT_ARCH_AMD64
    54895778        mov     rax, [pvBitmap]
    54905779        bts     [rax], edx
    5491 else
     5780 else
    54925781        mov     eax, [pvBitmap]
    54935782        bts     [eax], edx
    5494 endif
     5783 endif
    54955784        setc    al
    54965785        and     eax, 1
    54975786        mov     [rc.u32], eax
    54985787    }
     5788#  endif
     5789
     5790# else
     5791    int32_t offBitmap = iBit / 32;
     5792    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
     5793    rc.u32 = ASMAtomicUoOrExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31)) >> (iBit & 31);
    54995794# endif
    55005795    return rc.f;
     
    55155810 * @remarks x86: Requires a 386 or later.
    55165811 */
    5517 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5812#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    55185813RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicBitTestAndSet(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    55195814#else
     
    55245819# if RT_INLINE_ASM_USES_INTRIN
    55255820    rc.u8 = _interlockedbittestandset((long RT_FAR *)pvBitmap, iBit);
    5526 # elif RT_INLINE_ASM_GNU_STYLE
     5821# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5822#  if RT_INLINE_ASM_GNU_STYLE
    55275823    __asm__ __volatile__("lock; btsl %2, %1\n\t"
    55285824                         "setc %b0\n\t"
     
    55345830                         : "memory"
    55355831                         , "cc");
    5536 # else
     5832#  else
    55375833    __asm
    55385834    {
    55395835        mov     edx, [iBit]
    5540 ifdef RT_ARCH_AMD64
     5836 ifdef RT_ARCH_AMD64
    55415837        mov     rax, [pvBitmap]
    55425838        lock bts [rax], edx
    5543 else
     5839 else
    55445840        mov     eax, [pvBitmap]
    55455841        lock bts [eax], edx
    5546 endif
     5842 endif
    55475843        setc    al
    55485844        and     eax, 1
    55495845        mov     [rc.u32], eax
    55505846    }
     5847#  endif
     5848
     5849# else
     5850    rc.u32 = ASMAtomicOrExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31)) >> (iBit & 31);
    55515851# endif
    55525852    return rc.f;
     
    55685868 *          traps accessing the last bits in the bitmap.
    55695869 */
    5570 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5870#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    55715871RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMBitTestAndClear(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    55725872#else
     
    55775877    rc.u8 = _bittestandreset((long RT_FAR *)pvBitmap, iBit);
    55785878
    5579 # elif RT_INLINE_ASM_GNU_STYLE
     5879# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5880#  if RT_INLINE_ASM_GNU_STYLE
    55805881    __asm__ __volatile__("btrl %2, %1\n\t"
    55815882                         "setc %b0\n\t"
     
    55875888                         : "memory"
    55885889                         , "cc");
    5589 # else
     5890#  else
    55905891    __asm
    55915892    {
    55925893        mov     edx, [iBit]
    5593 ifdef RT_ARCH_AMD64
     5894 ifdef RT_ARCH_AMD64
    55945895        mov     rax, [pvBitmap]
    55955896        btr     [rax], edx
    5596 else
     5897 else
    55975898        mov     eax, [pvBitmap]
    55985899        btr     [eax], edx
    5599 endif
     5900 endif
    56005901        setc    al
    56015902        and     eax, 1
    56025903        mov     [rc.u32], eax
    56035904    }
     5905#  endif
     5906
     5907# else
     5908    int32_t offBitmap = iBit / 32;
     5909    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
     5910    rc.u32 = ASMAtomicUoAndExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], ~RT_BIT_32(iBit & 31)) >> (iBit & 31);
    56045911# endif
    56055912    return rc.f;
     
    56215928 * @remarks x86: Requires a 386 or later.
    56225929 */
    5623 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5930#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    56245931RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicBitTestAndClear(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    56255932#else
     
    56315938    rc.u8 = _interlockedbittestandreset((long RT_FAR *)pvBitmap, iBit);
    56325939
    5633 # elif RT_INLINE_ASM_GNU_STYLE
     5940# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5941#  if RT_INLINE_ASM_GNU_STYLE
    56345942    __asm__ __volatile__("lock; btrl %2, %1\n\t"
    56355943                         "setc %b0\n\t"
     
    56415949                         : "memory"
    56425950                         , "cc");
    5643 # else
     5951#  else
    56445952    __asm
    56455953    {
    56465954        mov     edx, [iBit]
    5647 ifdef RT_ARCH_AMD64
     5955 ifdef RT_ARCH_AMD64
    56485956        mov     rax, [pvBitmap]
    56495957        lock btr [rax], edx
    5650 else
     5958 else
    56515959        mov     eax, [pvBitmap]
    56525960        lock btr [eax], edx
    5653 endif
     5961 endif
    56545962        setc    al
    56555963        and     eax, 1
    56565964        mov     [rc.u32], eax
    56575965    }
     5966#  endif
     5967
     5968# else
     5969    rc.u32 = ASMAtomicAndExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], ~RT_BIT_32(iBit & 31)) >> (iBit & 31);
    56585970# endif
    56595971    return rc.f;
     
    56755987 *          traps accessing the last bits in the bitmap.
    56765988 */
    5677 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     5989#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    56785990RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMBitTestAndToggle(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    56795991#else
     
    56845996    rc.u8 = _bittestandcomplement((long RT_FAR *)pvBitmap, iBit);
    56855997
    5686 # elif RT_INLINE_ASM_GNU_STYLE
     5998# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     5999#  if RT_INLINE_ASM_GNU_STYLE
    56876000    __asm__ __volatile__("btcl %2, %1\n\t"
    56886001                         "setc %b0\n\t"
     
    56946007                         : "memory"
    56956008                         , "cc");
    5696 # else
     6009#  else
    56976010    __asm
    56986011    {
    56996012        mov   edx, [iBit]
    5700 ifdef RT_ARCH_AMD64
     6013 ifdef RT_ARCH_AMD64
    57016014        mov   rax, [pvBitmap]
    57026015        btc   [rax], edx
    5703 else
     6016 else
    57046017        mov   eax, [pvBitmap]
    57056018        btc   [eax], edx
    5706 endif
     6019 endif
    57076020        setc  al
    57086021        and   eax, 1
    57096022        mov   [rc.u32], eax
    57106023    }
     6024#  endif
     6025
     6026# else
     6027    int32_t offBitmap = iBit / 32;
     6028    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
     6029    rc.u32 = ASMAtomicUoXorExU32(&((uint32_t volatile *)pvBitmap)[offBitmap], RT_BIT_32(iBit & 31)) >> (iBit & 31);
    57116030# endif
    57126031    return rc.f;
     
    57276046 * @remarks x86: Requires a 386 or later.
    57286047 */
    5729 #if RT_INLINE_ASM_EXTERNAL
     6048#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    57306049RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMAtomicBitTestAndToggle(volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    57316050#else
     
    57346053    union { bool f; uint32_t u32; uint8_t u8; } rc;
    57356054    AssertMsg(!((uintptr_t)pvBitmap & 3), ("address %p not 32-bit aligned", pvBitmap));
    5736 # if RT_INLINE_ASM_GNU_STYLE
     6055# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6056#  if RT_INLINE_ASM_GNU_STYLE
    57376057    __asm__ __volatile__("lock; btcl %2, %1\n\t"
    57386058                         "setc %b0\n\t"
     
    57446064                         : "memory"
    57456065                         , "cc");
    5746 # else
     6066#  else
    57476067    __asm
    57486068    {
    57496069        mov     edx, [iBit]
    5750 ifdef RT_ARCH_AMD64
     6070 ifdef RT_ARCH_AMD64
    57516071        mov     rax, [pvBitmap]
    57526072        lock btc [rax], edx
    5753 else
     6073 else
    57546074        mov     eax, [pvBitmap]
    57556075        lock btc [eax], edx
    5756 endif
     6076 endif
    57576077        setc    al
    57586078        and     eax, 1
    57596079        mov     [rc.u32], eax
    57606080    }
     6081#  endif
     6082
     6083# else
     6084    rc.u32 = ASMAtomicXorExU32(&((uint32_t volatile *)pvBitmap)[iBit / 32], RT_BIT_32(iBit & 31)) >> (iBit & 31);
    57616085# endif
    57626086    return rc.f;
     
    57786102 *          traps accessing the last bits in the bitmap.
    57796103 */
    5780 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     6104#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    57816105RT_ASM_DECL_PRAGMA_WATCOM(bool) ASMBitTest(const volatile void RT_FAR *pvBitmap, int32_t iBit) RT_NOTHROW_PROTO;
    57826106#else
     
    57866110# if RT_INLINE_ASM_USES_INTRIN
    57876111    rc.u32 = _bittest((long *)pvBitmap, iBit);
    5788 # elif RT_INLINE_ASM_GNU_STYLE
     6112
     6113# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     6114#  if RT_INLINE_ASM_GNU_STYLE
    57896115
    57906116    __asm__ __volatile__("btl %2, %1\n\t"
     
    57966122                         : "memory"
    57976123                         , "cc");
    5798 # else
     6124#  else
    57996125    __asm
    58006126    {
    58016127        mov   edx, [iBit]
    5802 ifdef RT_ARCH_AMD64
     6128 ifdef RT_ARCH_AMD64
    58036129        mov   rax, [pvBitmap]
    58046130        bt    [rax], edx
    5805 else
     6131 else
    58066132        mov   eax, [pvBitmap]
    58076133        bt    [eax], edx
    5808 endif
     6134 endif
    58096135        setc  al
    58106136        and   eax, 1
    58116137        mov   [rc.u32], eax
    58126138    }
     6139#  endif
     6140
     6141# else
     6142    int32_t offBitmap = iBit / 32;
     6143    AssertStmt(!((uintptr_t)pvBitmap & 3), offBitmap += (uintptr_t)pvBitmap & 3; iBit += ((uintptr_t)pvBitmap & 3) * 8);
     6144    rc.u32 = ASMAtomicUoReadU32(&((uint32_t volatile *)pvBitmap)[offBitmap]) >> (iBit & 31);
    58136145# endif
    58146146    return rc.f;
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