VirtualBox

Changeset 102940 in vbox


Ignore:
Timestamp:
Jan 17, 2024 11:23:30 PM (13 months ago)
Author:
vboxsync
Message:

iprt/asm.h: Working over the ASMAtomic*Read* functions for arm64 w/ optional use of LSE instructions. bugref:9898

File:
1 edited

Legend:

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

    r102939 r102940  
    27112711#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    27122712    uint32_t u32;
     2713# if defined(RTASM_ARM64_USE_FEAT_LSE) && 0 /* very expensive on M1 */
    27132714    __asm__ __volatile__("Lstart_ASMAtomicReadU8_%=:\n\t"
    27142715                         RTASM_ARM_DMB_SY
    2715 # if defined(RT_ARCH_ARM64)
     2716                         "casab     %w[uDst], wzr, %[pMem]\n\t"
     2717                         : [uDst] "=&r" (u32)
     2718                         : [pMem] "Q" (*pu8),
     2719                           "0" (0)
     2720                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2721# else
     2722    __asm__ __volatile__("Lstart_ASMAtomicReadU8_%=:\n\t"
     2723                         RTASM_ARM_DMB_SY
     2724#  if defined(RT_ARCH_ARM64)
     2725#   if 1 /* shouldn't be any need for more than single-copy atomicity when we've got a proper barrier, just like on x86. */
     2726                         "ldurb     %w[uDst], %[pMem]\n\t"
     2727#   else
    27162728                         "ldxrb     %w[uDst], %[pMem]\n\t"
    2717 # else
     2729                         "clrex\n\t"
     2730#   endif
     2731#  else
    27182732                         "ldrexb    %[uDst], %[pMem]\n\t"
    2719 # endif
     2733                         /** @todo clrex   */
     2734#  endif
    27202735                         : [uDst] "=&r" (u32)
    27212736                         : [pMem] "Q" (*pu8)
    27222737                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2738# endif
    27232739    return (uint8_t)u32;
    27242740#else
     
    27412757    __asm__ __volatile__("Lstart_ASMAtomicUoReadU8_%=:\n\t"
    27422758# if defined(RT_ARCH_ARM64)
    2743                          "ldxrb     %w[uDst], %[pMem]\n\t"
    2744 # else
    2745                          "ldrexb    %[uDst], %[pMem]\n\t"
     2759                         "ldurb    %w[uDst], %[pMem]\n\t"
     2760# else
     2761                         "ldrexb    %[uDst], %[pMem]\n\t" /** @todo fix this */
    27462762# endif
    27472763                         : [uDst] "=&r" (u32)
     
    27622778DECLINLINE(int8_t) ASMAtomicReadS8(volatile int8_t RT_FAR *pi8) RT_NOTHROW_DEF
    27632779{
     2780#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
     2781    return (int8_t)ASMAtomicReadU8((volatile uint8_t RT_FAR *)pi8);
     2782#else
    27642783    ASMMemoryFence();
    2765 #if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    2766     int32_t i32;
    2767     __asm__ __volatile__("Lstart_ASMAtomicReadS8_%=:\n\t"
    2768                          RTASM_ARM_DMB_SY
    2769 # if defined(RT_ARCH_ARM64)
    2770                          "ldxrb     %w[iDst], %[pMem]\n\t"
    2771 # else
    2772                          "ldrexb    %[iDst], %[pMem]\n\t"
    2773 # endif
    2774                          : [iDst] "=&r" (i32)
    2775                          : [pMem] "Q" (*pi8)
    2776                            RTASM_ARM_DMB_SY_COMMA_IN_REG);
    2777     return (int8_t)i32;
    2778 #else
    27792784    return *pi8;    /* byte reads are atomic on x86 */
    27802785#endif
     
    27942799    __asm__ __volatile__("Lstart_ASMAtomicUoReadS8_%=:\n\t"
    27952800# if defined(RT_ARCH_ARM64)
    2796                          "ldxrb     %w[iDst], %[pMem]\n\t"
    2797 # else
    2798                          "ldrexb    %[iDst], %[pMem]\n\t"
     2801                         "ldurb     %w[iDst], %[pMem]\n\t"
     2802# else
     2803                         "ldrexb    %[iDst], %[pMem]\n\t" /** @todo fix this */
    27992804# endif
    28002805                         : [iDst] "=&r" (i32)
     
    28182823#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    28192824    uint32_t u32;
     2825# if defined(RTASM_ARM64_USE_FEAT_LSE) && 0 /* very expensive on M1, but alignment advantages with LEA2 (M2?). */
    28202826    __asm__ __volatile__("Lstart_ASMAtomicReadU16_%=:\n\t"
    28212827                         RTASM_ARM_DMB_SY
    2822 # if defined(RT_ARCH_ARM64)
     2828                         "casah     %w[uDst], wzr, %[pMem]\n\t"
     2829                         : [uDst] "=&r" (u32)
     2830                         : [pMem] "Q" (*pu16),
     2831                           "0" (0)
     2832                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2833# else
     2834    __asm__ __volatile__("Lstart_ASMAtomicReadU16_%=:\n\t"
     2835                         RTASM_ARM_DMB_SY
     2836#  if defined(RT_ARCH_ARM64)
     2837#   if 1 /* ASSUMING proper barrier and aligned access, we should be fine with single-copy atomicity, just like on x86. */
     2838                         "ldurh     %w[uDst], %[pMem]\n\t"
     2839#   else
    28232840                         "ldxrh     %w[uDst], %[pMem]\n\t"
    2824 # else
     2841                         "clrex\n\t"
     2842#   endif
     2843#  else
    28252844                         "ldrexh    %[uDst], %[pMem]\n\t"
    2826 # endif
     2845                         /** @todo clrex    */
     2846#  endif
    28272847                         : [uDst] "=&r" (u32)
    28282848                         : [pMem] "Q" (*pu16)
    28292849                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2850# endif
    28302851    return (uint16_t)u32;
    28312852#else
     
    28492870    __asm__ __volatile__("Lstart_ASMAtomicUoReadU16_%=:\n\t"
    28502871# if defined(RT_ARCH_ARM64)
    2851                          "ldxrh     %w[uDst], %[pMem]\n\t"
    2852 # else
    2853                          "ldrexh    %[uDst], %[pMem]\n\t"
     2872                         "ldurh     %w[uDst], %[pMem]\n\t"
     2873# else
     2874                         "ldrexh    %[uDst], %[pMem]\n\t" /** @todo fix this */
    28542875# endif
    28552876                         : [uDst] "=&r" (u32)
     
    28722893    Assert(!((uintptr_t)pi16 & 1));
    28732894#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    2874     int32_t i32;
    2875     __asm__ __volatile__("Lstart_ASMAtomicReadS16_%=:\n\t"
    2876                          RTASM_ARM_DMB_SY
    2877 # if defined(RT_ARCH_ARM64)
    2878                          "ldxrh     %w[iDst], %[pMem]\n\t"
    2879 # else
    2880                          "ldrexh    %[iDst], %[pMem]\n\t"
    2881 # endif
    2882                          : [iDst] "=&r" (i32)
    2883                          : [pMem] "Q" (*pi16)
    2884                            RTASM_ARM_DMB_SY_COMMA_IN_REG);
    2885     return (int16_t)i32;
     2895    return (int16_t)ASMAtomicReadU16((volatile uint16_t RT_FAR *)pi16);
    28862896#else
    28872897    ASMMemoryFence();
     
    29042914    __asm__ __volatile__("Lstart_ASMAtomicUoReadS16_%=:\n\t"
    29052915# if defined(RT_ARCH_ARM64)
    2906                          "ldxrh     %w[iDst], %[pMem]\n\t"
    2907 # else
    2908                          "ldrexh    %[iDst], %[pMem]\n\t"
     2916                         "ldurh     %w[iDst], %[pMem]\n\t"
     2917# else
     2918                         "ldrexh    %[iDst], %[pMem]\n\t" /** @todo fix this */
    29092919# endif
    29102920                         : [iDst] "=&r" (i32)
     
    29282938#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    29292939    uint32_t u32;
     2940# if defined(RTASM_ARM64_USE_FEAT_LSE) && 0 /* very expensive on M1, but alignment advantages with LEA2 (M2?). */
    29302941    __asm__ __volatile__("Lstart_ASMAtomicReadU32_%=:\n\t"
    29312942                         RTASM_ARM_DMB_SY
    2932 # if defined(RT_ARCH_ARM64)
     2943                         "casa      %w[uDst], wzr, %[pMem]\n\t"
     2944                         : [uDst] "=&r" (u32)
     2945                         : [pMem] "Q" (*pu32),
     2946                           "0" (0)
     2947                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2948# else
     2949    __asm__ __volatile__("Lstart_ASMAtomicReadU32_%=:\n\t"
     2950                         RTASM_ARM_DMB_SY
     2951#  if defined(RT_ARCH_ARM64)
     2952#   if 1 /* ASSUMING proper barrier and aligned access, we should be fine with single-copy atomicity, just like on x86. */
     2953                         "ldur      %w[uDst], %[pMem]\n\t"
     2954#   else
    29332955                         "ldxr      %w[uDst], %[pMem]\n\t"
    2934 # else
     2956                         "clrex\n\t"
     2957#   endif
     2958#  else
    29352959                         "ldrex    %[uDst], %[pMem]\n\t"
    2936 # endif
     2960                         /** @todo clrex    */
     2961#  endif
    29372962                         : [uDst] "=&r" (u32)
    29382963                         : [pMem] "Q" (*pu32)
    29392964                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     2965# endif
    29402966    return u32;
    29412967#else
     
    29622988    __asm__ __volatile__("Lstart_ASMAtomicUoReadU32_%=:\n\t"
    29632989# if defined(RT_ARCH_ARM64)
    2964                          "ldxr      %w[uDst], %[pMem]\n\t"
    2965 # else
    2966                          "ldrex    %[uDst], %[pMem]\n\t"
     2990                         "ldur      %w[uDst], %[pMem]\n\t"
     2991# else
     2992                         "ldrex     %[uDst], %[pMem]\n\t" /** @todo fix this */
    29672993# endif
    29682994                         : [uDst] "=&r" (u32)
     
    29883014    Assert(!((uintptr_t)pi32 & 3));
    29893015#if defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    2990     int32_t i32;
    2991     __asm__ __volatile__("Lstart_ASMAtomicReadS32_%=:\n\t"
    2992                          RTASM_ARM_DMB_SY
    2993 # if defined(RT_ARCH_ARM64)
    2994                          "ldxr      %w[iDst], %[pMem]\n\t"
    2995 # else
    2996                          "ldrex    %[iDst], %[pMem]\n\t"
    2997 # endif
    2998                          : [iDst] "=&r" (i32)
    2999                          : [pMem] "Q" (*pi32)
    3000                            RTASM_ARM_DMB_SY_COMMA_IN_REG);
    3001     return i32;
     3016    return (int32_t)ASMAtomicReadU32((volatile uint32_t RT_FAR *)pi32);
    30023017#else
    30033018    ASMMemoryFence();
     
    30233038    __asm__ __volatile__("Lstart_ASMAtomicUoReadS32_%=:\n\t"
    30243039# if defined(RT_ARCH_ARM64)
    3025                          "ldxr      %w[iDst], %[pMem]\n\t"
    3026 # else
    3027                          "ldrex    %[iDst], %[pMem]\n\t"
     3040                         "ldur      %w[iDst], %[pMem]\n\t"
     3041# else
     3042                         "ldrex     %[iDst], %[pMem]\n\t" /** @todo thix this */
    30283043# endif
    30293044                         : [iDst] "=&r" (i32)
     
    31213136# elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    31223137    Assert(!((uintptr_t)pu64 & 7));
     3138
     3139# if defined(RTASM_ARM64_USE_FEAT_LSE) && 0 /* very expensive on M1, but alignment advantages with LEA2 (M2?). */
    31233140    __asm__ __volatile__("Lstart_ASMAtomicReadU64_%=:\n\t"
    31243141                         RTASM_ARM_DMB_SY
    3125 # if defined(RT_ARCH_ARM64)
     3142                         "casa      %[uDst], xzr, %[pMem]\n\t"
     3143                         : [uDst] "=&r" (u64)
     3144                         : [pMem] "Q" (*pu64),
     3145                           "0" (0)
     3146                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
     3147# else
     3148    __asm__ __volatile__("Lstart_ASMAtomicReadU64_%=:\n\t"
     3149                         RTASM_ARM_DMB_SY
     3150#   if defined(RT_ARCH_ARM64)
     3151#    if 1 /* ASSUMING proper barrier and aligned access, we should be fine with single-copy atomicity, just like on x86. */
     3152                         "ldur      %[uDst], %[pMem]\n\t"
     3153#    else
    31263154                         "ldxr      %[uDst], %[pMem]\n\t"
    3127 # else
     3155                         "clrex\n\t"
     3156#    endif
     3157#   else
    31283158                         "ldrexd    %[uDst], %H[uDst], %[pMem]\n\t"
    3129 # endif
     3159                         /** @todo clrex    */
     3160#   endif
    31303161                         : [uDst] "=&r" (u64)
    31313162                         : [pMem] "Q" (*pu64)
    31323163                           RTASM_ARM_DMB_SY_COMMA_IN_REG);
    3133 
     3164#  endif
    31343165# else
    31353166#  error "Port me"
     
    32253256    __asm__ __volatile__("Lstart_ASMAtomicUoReadU64_%=:\n\t"
    32263257# if defined(RT_ARCH_ARM64)
    3227                          "ldxr      %[uDst], %[pMem]\n\t"
    3228 # else
    3229                          "ldrexd    %[uDst], %H[uDst], %[pMem]\n\t"
     3258                         "ldur      %[uDst], %[pMem]\n\t"
     3259# else
     3260                         "ldrexd    %[uDst], %H[uDst], %[pMem]\n\t" /* this is required for atomic access since it's a pair */
     3261                         /** @todo clrex? */
    32303262# endif
    32313263                         : [uDst] "=&r" (u64)
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