VirtualBox

Changeset 87183 in vbox for trunk/include/iprt


Ignore:
Timestamp:
Jan 6, 2021 12:12:34 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142114
Message:

iprt/asm.h: More fun. bugref:9898 bugref:9026

File:
1 edited

Legend:

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

    r87181 r87183  
    439439 * spin locks.
    440440 */
    441 #if RT_INLINE_ASM_EXTERNAL && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
     441#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
    442442RT_ASM_DECL_PRAGMA_WATCOM(void) ASMNopPause(void) RT_NOTHROW_PROTO;
    443443#else
     
    24822482    Assert(!((uintptr_t)pi32 & 3));
    24832483#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    2484     Assert(!((uintptr_t)pu64 & 7));
     2484    Assert(!((uintptr_t)pi32 & 7));
    24852485    int32_t i32;
    24862486    __asm__ __volatile__(".Lstart_ASMAtomicUoReadS32_%=:\n\t"
     
    41444144 * @remarks x86: Requires a 386 or later.
    41454145 */
    4146 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4146#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    41474147RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicOrU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
    41484148#else
     
    41524152    _InterlockedOr((long volatile RT_FAR *)pu32, (long)u32);
    41534153
    4154 # elif RT_INLINE_ASM_GNU_STYLE
     4154# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4155#  if RT_INLINE_ASM_GNU_STYLE
    41554156    __asm__ __volatile__("lock; orl %1, %0\n\t"
    41564157                         : "=m" (*pu32)
     
    41584159                         , "m" (*pu32)
    41594160                         : "cc");
    4160 # else
     4161#  else
    41614162    __asm
    41624163    {
    41634164        mov     eax, [u32]
    4164 ifdef RT_ARCH_AMD64
     4165 ifdef RT_ARCH_AMD64
    41654166        mov     rdx, [pu32]
    41664167        lock    or [rdx], eax
    4167 else
     4168 else
    41684169        mov     edx, [pu32]
    41694170        lock    or [edx], eax
    4170 endif
     4171 endif
    41714172    }
     4173#  endif
     4174
     4175# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4176    /* For more on Orr see https://en.wikipedia.org/wiki/Orr_(Catch-22) ;-) */
     4177    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicOr32, pu32, DMB_SY,
     4178                                           "orr %w[uNew], %w[uNew], %w[uVal]\n\t",
     4179                                           "orr %[uNew], %[uNew], %[uVal]\n\t",
     4180                                           [uVal] "r" (u32));
     4181
     4182# else
     4183#  error "Port me"
    41724184# endif
    41734185}
     
    41974209 * @remarks x86: Requires a Pentium or later.
    41984210 */
    4199 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4211#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    42004212DECLASM(void) ASMAtomicOrU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO;
    42014213#else
     
    42114223                         , "m" (*pu64)
    42124224                         : "cc");
     4225
     4226# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4227    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_64(ASMAtomicOrU64, pu64, DMB_SY,
     4228                                           "orr %[uNew], %[uNew], %[uVal]\n\t"
     4229                                           ,
     4230                                           "orr %[uNew], %[uNew], %[uVal]\n\t"
     4231                                           "orr %H[uNew], %H[uNew], %H[uVal]\n\t",
     4232                                           [uVal] "r" (u64));
     4233
    42134234# else
    42144235    for (;;)
     
    42474268 * @remarks x86: Requires a 386 or later.
    42484269 */
    4249 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4270#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    42504271RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicAndU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
    42514272#else
     
    42554276    _InterlockedAnd((long volatile RT_FAR *)pu32, u32);
    42564277
    4257 # elif RT_INLINE_ASM_GNU_STYLE
     4278# elif defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4279#  if RT_INLINE_ASM_GNU_STYLE
    42584280    __asm__ __volatile__("lock; andl %1, %0\n\t"
    42594281                         : "=m" (*pu32)
     
    42614283                         , "m" (*pu32)
    42624284                         : "cc");
    4263 # else
     4285#  else
    42644286    __asm
    42654287    {
    42664288        mov     eax, [u32]
    4267 ifdef RT_ARCH_AMD64
     4289 ifdef RT_ARCH_AMD64
    42684290        mov     rdx, [pu32]
    42694291        lock and [rdx], eax
    4270 else
     4292 else
    42714293        mov     edx, [pu32]
    42724294        lock and [edx], eax
    4273 endif
     4295 endif
    42744296    }
     4297#  endif
     4298
     4299# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4300    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicAnd32, pu32, DMB_SY,
     4301                                           "and %w[uNew], %w[uNew], %w[uVal]\n\t",
     4302                                           "and %[uNew], %[uNew], %[uVal]\n\t",
     4303                                           [uVal] "r" (u32));
     4304
     4305# else
     4306#  error "Port me"
    42754307# endif
    42764308}
     
    43004332 * @remarks x86: Requires a Pentium or later.
    43014333 */
    4302 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4334#if RT_INLINE_ASM_EXTERNAL_TMP_ARM && !RT_INLINE_ASM_USES_INTRIN
    43034335DECLASM(void) ASMAtomicAndU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO;
    43044336#else
     
    43144346                         , "m" (*pu64)
    43154347                         : "cc");
     4348
     4349# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4350    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_64(ASMAtomicAndU64, pu64, DMB_SY,
     4351                                           "and %[uNew], %[uNew], %[uVal]\n\t"
     4352                                           ,
     4353                                           "and %[uNew], %[uNew], %[uVal]\n\t"
     4354                                           "and %H[uNew], %H[uNew], %H[uVal]\n\t",
     4355                                           [uVal] "r" (u64));
     4356
    43164357# else
    43174358    for (;;)
     
    43504391 * @remarks x86: Requires a 386 or later.
    43514392 */
    4352 #if RT_INLINE_ASM_EXTERNAL
     4393#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    43534394RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicUoOrU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
    43544395#else
    43554396DECLINLINE(void) ASMAtomicUoOrU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
    43564397{
    4357 # if RT_INLINE_ASM_GNU_STYLE
     4398# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4399#  if RT_INLINE_ASM_GNU_STYLE
    43584400    __asm__ __volatile__("orl %1, %0\n\t"
    43594401                         : "=m" (*pu32)
     
    43614403                         , "m" (*pu32)
    43624404                         : "cc");
    4363 # else
     4405#  else
    43644406    __asm
    43654407    {
    43664408        mov     eax, [u32]
    4367 ifdef RT_ARCH_AMD64
     4409 ifdef RT_ARCH_AMD64
    43684410        mov     rdx, [pu32]
    43694411        or      [rdx], eax
    4370 else
     4412 else
    43714413        mov     edx, [pu32]
    43724414        or      [edx], eax
    4373 endif
     4415 endif
    43744416    }
     4417#  endif
     4418
     4419# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4420    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicUoOr32, pu32, NO_BARRIER,
     4421                                           "orr %w[uNew], %w[uNew], %w[uVal]\n\t",
     4422                                           "orr %[uNew], %[uNew], %[uVal]\n\t",
     4423                                           [uVal] "r" (u32));
     4424
     4425# else
     4426#  error "Port me"
    43754427# endif
    43764428}
     
    44004452 * @remarks x86: Requires a Pentium or later.
    44014453 */
    4402 #if RT_INLINE_ASM_EXTERNAL
     4454#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    44034455DECLASM(void) ASMAtomicUoOrU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO;
    44044456#else
     
    44114463                         , "m" (*pu64)
    44124464                         : "cc");
     4465
     4466# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4467    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_64(ASMAtomicUoOrU64, pu64, NO_BARRIER,
     4468                                           "orr %[uNew], %[uNew], %[uVal]\n\t"
     4469                                           ,
     4470                                           "orr %[uNew], %[uNew], %[uVal]\n\t"
     4471                                           "orr %H[uNew], %H[uNew], %H[uVal]\n\t",
     4472                                           [uVal] "r" (u64));
     4473
    44134474# else
    44144475    for (;;)
     
    44474508 * @remarks x86: Requires a 386 or later.
    44484509 */
    4449 #if RT_INLINE_ASM_EXTERNAL
     4510#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    44504511RT_ASM_DECL_PRAGMA_WATCOM(void) ASMAtomicUoAndU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_PROTO;
    44514512#else
    44524513DECLINLINE(void) ASMAtomicUoAndU32(uint32_t volatile RT_FAR *pu32, uint32_t u32) RT_NOTHROW_DEF
    44534514{
    4454 # if RT_INLINE_ASM_GNU_STYLE
     4515# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     4516#  if RT_INLINE_ASM_GNU_STYLE
    44554517    __asm__ __volatile__("andl %1, %0\n\t"
    44564518                         : "=m" (*pu32)
     
    44584520                         , "m" (*pu32)
    44594521                         : "cc");
    4460 # else
     4522#  else
    44614523    __asm
    44624524    {
    44634525        mov     eax, [u32]
    4464 ifdef RT_ARCH_AMD64
     4526 ifdef RT_ARCH_AMD64
    44654527        mov     rdx, [pu32]
    44664528        and     [rdx], eax
    4467 else
     4529 else
    44684530        mov     edx, [pu32]
    44694531        and     [edx], eax
    4470 endif
     4532 endif
    44714533    }
     4534#  endif
     4535
     4536# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4537    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicUoAnd32, pu32, NO_BARRIER,
     4538                                           "and %w[uNew], %w[uNew], %w[uVal]\n\t",
     4539                                           "and %[uNew], %[uNew], %[uVal]\n\t",
     4540                                           [uVal] "r" (u32));
     4541
     4542# else
     4543#  error "Port me"
    44724544# endif
    44734545}
     
    44974569 * @remarks x86: Requires a Pentium or later.
    44984570 */
    4499 #if RT_INLINE_ASM_EXTERNAL
     4571#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    45004572DECLASM(void) ASMAtomicUoAndU64(uint64_t volatile RT_FAR *pu64, uint64_t u64) RT_NOTHROW_PROTO;
    45014573#else
     
    45084580                         , "m" (*pu64)
    45094581                         : "cc");
     4582
     4583# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4584    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_64(ASMAtomicUoAndU64, pu64, NO_BARRIER,
     4585                                           "and %[uNew], %[uNew], %[uVal]\n\t"
     4586                                           ,
     4587                                           "and %[uNew], %[uNew], %[uVal]\n\t"
     4588                                           "and %H[uNew], %H[uNew], %H[uVal]\n\t",
     4589                                           [uVal] "r" (u64));
     4590
    45104591# else
    45114592    for (;;)
     
    45444625 * @remarks x86: Requires a 486 or later.
    45454626 */
    4546 #if RT_INLINE_ASM_EXTERNAL
     4627#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    45474628RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicUoIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO;
    45484629#else
    45494630DECLINLINE(uint32_t) ASMAtomicUoIncU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF
    45504631{
     4632# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    45514633    uint32_t u32;
    4552 # if RT_INLINE_ASM_GNU_STYLE
     4634#  if RT_INLINE_ASM_GNU_STYLE
    45534635    __asm__ __volatile__("xaddl %0, %1\n\t"
    45544636                         : "=r" (u32)
     
    45594641                         , "cc");
    45604642    return u32 + 1;
    4561 # else
     4643#  else
    45624644    __asm
    45634645    {
    45644646        mov     eax, 1
    4565 ifdef RT_ARCH_AMD64
     4647 ifdef RT_ARCH_AMD64
    45664648        mov     rdx, [pu32]
    45674649        xadd    [rdx], eax
    4568 else
     4650 else
    45694651        mov     edx, [pu32]
    45704652        xadd    [edx], eax
    4571 endif
     4653 endif
    45724654        mov     u32, eax
    45734655    }
    45744656    return u32 + 1;
     4657#  endif
     4658
     4659# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4660    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicUoIncU32, pu32, NO_BARRIER,
     4661                                           "add %w[uNew], %w[uNew], #1\n\t",
     4662                                           "add %[uNew], %[uNew], #1\n\t" /* arm6 / thumb2+ */,
     4663                                           "X" (0) /* dummy */);
     4664    return u32NewRet;
     4665
     4666# else
     4667#  error "Port me"
    45754668# endif
    45764669}
     
    45864679 * @remarks x86: Requires a 486 or later.
    45874680 */
    4588 #if RT_INLINE_ASM_EXTERNAL
     4681#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    45894682RT_ASM_DECL_PRAGMA_WATCOM(uint32_t) ASMAtomicUoDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_PROTO;
    45904683#else
    45914684DECLINLINE(uint32_t) ASMAtomicUoDecU32(uint32_t volatile RT_FAR *pu32) RT_NOTHROW_DEF
    45924685{
     4686# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    45934687    uint32_t u32;
    4594 # if RT_INLINE_ASM_GNU_STYLE
     4688#  if RT_INLINE_ASM_GNU_STYLE
    45954689    __asm__ __volatile__("lock; xaddl %0, %1\n\t"
    45964690                         : "=r" (u32)
     
    46014695                         , "cc");
    46024696    return u32 - 1;
    4603 # else
     4697#  else
    46044698    __asm
    46054699    {
    46064700        mov     eax, -1
    4607 ifdef RT_ARCH_AMD64
     4701 ifdef RT_ARCH_AMD64
    46084702        mov     rdx, [pu32]
    46094703        xadd    [rdx], eax
    4610 else
     4704 else
    46114705        mov     edx, [pu32]
    46124706        xadd    [edx], eax
    4613 endif
     4707 endif
    46144708        mov     u32, eax
    46154709    }
    46164710    return u32 - 1;
     4711#  endif
     4712
     4713# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     4714    RTASM_ARM_LOAD_MODIFY_STORE_RET_NEW_32(ASMAtomicUoDecU32, pu32, NO_BARRIER,
     4715                                           "sub %w[uNew], %w[uNew], #1\n\t",
     4716                                           "sub %[uNew], %[uNew], #1\n\t" /* arm6 / thumb2+ */,
     4717                                           "X" (0) /* dummy */);
     4718    return u32NewRet;
     4719
     4720# else
     4721#  error "Port me"
    46174722# endif
    46184723}
     
    46524757 * @param   pv  Pointer to the memory block. This must be page aligned.
    46534758 */
    4654 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4759#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
    46554760RT_ASM_DECL_PRAGMA_WATCOM(void) ASMMemZeroPage(volatile void RT_FAR *pv) RT_NOTHROW_PROTO;
    46564761# else
     
    47094814 * @param   cb  Number of bytes in the block. This MUST be aligned on 32-bit!
    47104815 */
    4711 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4816#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
    47124817RT_ASM_DECL_PRAGMA_WATCOM(void) ASMMemZero32(volatile void RT_FAR *pv, size_t cb) RT_NOTHROW_PROTO;
    47134818#else
     
    47574862 * @param   u32 The value to fill with.
    47584863 */
    4759 #if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
     4864#if (RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN) || defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64)
    47604865RT_ASM_DECL_PRAGMA_WATCOM(void) ASMMemFill32(volatile void RT_FAR *pv, size_t cb, uint32_t u32) RT_NOTHROW_PROTO;
    47614866#else
     
    49915096 * @param   pvByte      Pointer to the byte.
    49925097 */
    4993 #if RT_INLINE_ASM_EXTERNAL
     5098#if RT_INLINE_ASM_EXTERNAL_TMP_ARM
    49945099RT_ASM_DECL_PRAGMA_WATCOM(uint8_t) ASMProbeReadByte(const void RT_FAR *pvByte) RT_NOTHROW_PROTO;
    49955100#else
    49965101DECLINLINE(uint8_t) ASMProbeReadByte(const void RT_FAR *pvByte) RT_NOTHROW_DEF
    49975102{
     5103# if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    49985104    uint8_t u8;
    4999 # if RT_INLINE_ASM_GNU_STYLE
     5105#  if RT_INLINE_ASM_GNU_STYLE
    50005106    __asm__ __volatile__("movb (%1), %0\n\t"
    50015107                         : "=r" (u8)
    50025108                         : "r" (pvByte));
    5003 # else
     5109#  else
    50045110    __asm
    50055111    {
    5006 ifdef RT_ARCH_AMD64
     5112 ifdef RT_ARCH_AMD64
    50075113        mov     rax, [pvByte]
    50085114        mov     al, [rax]
    5009 else
     5115 else
    50105116        mov     eax, [pvByte]
    50115117        mov     al, [eax]
    5012 endif
     5118 endif
    50135119        mov     [u8], al
    50145120    }
    5015 # endif
     5121#  endif
    50165122    return u8;
     5123
     5124# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     5125    uint32_t u32;
     5126    __asm__ __volatile__(".Lstart_ASMProbeReadByte_%=:\n\t"
     5127#  if defined(RT_ARCH_ARM64)
     5128                         "ldxrb     %w[uDst], %[pMem]\n\t"
     5129#  else
     5130                         "ldrexb    %[uDst], %[pMem]\n\t"
     5131#  endif
     5132                         : [uDst] "=&r" (u32)
     5133                         : [pMem] "m" (*(uint8_t const *)pvByte));
     5134    return (uint8_t)u32;
     5135
     5136# else
     5137#  error "Port me"
     5138# endif
    50175139}
    50185140#endif
Note: See TracChangeset for help on using the changeset viewer.

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