r203816 - MS intrinsics: __interlockedbittestandset(64) (PR19054)

Hans Wennborg hans at chromium.org
Mon Mar 17 11:01:55 PDT 2014


On Thu, Mar 13, 2014 at 11:29 AM, David Majnemer
<david.majnemer at gmail.com> wrote:
> Couldn't this have been done without assembly?
>
> Something like:
>
> __sync_fetch_and_or(__BitBase, 1 << __BitPos)

Yes, but the code it generates is not very nice. I've filed PR19164
for that, but I'm hesitant to change this intrinsic right now.

I think the intrinsic would have to look like this:

  long __Mask = 1LL << __BitPos;
  return (__sync_fetch_and_or(__BitBase, __Mask) & (__Mask)) >> __BitPos;

Which we currently codegen as:

LBB0_1:
        movl    $128, %edx
        orl     %eax, %edx
        lock
        cmpxchgl        %edx, (%ecx)
        jne     LBB0_1
        shrl    $7, %eax
        andl    $1, %eax

I guess it's a trade-of between avoiding inline asm and generating nice code :/

 - Hans

> On Thu Mar 13 2014 at 10:13:20 AM, Hans Wennborg <hans at hanshq.net> wrote:
>>
>> Author: hans
>> Date: Thu Mar 13 12:05:09 2014
>> New Revision: 203816
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=203816&view=rev
>> Log:
>> MS intrinsics: __interlockedbittestandset(64) (PR19054)
>>
>> Modified:
>>     cfe/trunk/lib/Headers/Intrin.h
>>
>> Modified: cfe/trunk/lib/Headers/Intrin.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/Intrin.h?rev=203816&r1=203815&r2=203816&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Headers/Intrin.h (original)
>> +++ cfe/trunk/lib/Headers/Intrin.h Thu Mar 13 12:05:09 2014
>> @@ -195,6 +195,7 @@ short _InterlockedAnd16(short volatile *
>>  static __inline__
>>  char _InterlockedAnd8(char volatile *_Value, char _Mask);
>>  unsigned char _interlockedbittestandreset(long volatile *, long);
>> +static __inline__
>>  unsigned char _interlockedbittestandset(long volatile *, long);
>>  static __inline__
>>  long __cdecl _InterlockedCompareExchange(long volatile *_Destination,
>> @@ -390,6 +391,7 @@ short _InterlockedAnd16_np(short volatil
>>  __int64 _InterlockedAnd64_np(__int64 volatile *_Value, __int64 _Mask);
>>  char _InterlockedAnd8_np(char volatile *_Value, char _Mask);
>>  unsigned char _interlockedbittestandreset64(__int64 volatile *, __int64);
>> +static __inline__
>>  unsigned char _interlockedbittestandset64(__int64 volatile *, __int64);
>>  long _InterlockedCompareExchange_np(long volatile *_Destination, long
>> _Exchange,
>>                                      long _Comparand);
>> @@ -572,6 +574,16 @@ _bittestandset(long *a, long b) {
>>    *a = *a | (1 << b);
>>    return x;
>>  }
>> +static __inline__ unsigned char __attribute__((__always_inline__,
>> __nodebug__))
>> +_interlockedbittestandset(long volatile *__BitBase, long __BitPos) {
>> +  unsigned char __Res;
>> +  __asm__ ("xor %0, %0\n"
>> +           "lock bts %2, %1\n"
>> +           "setc %0\n"
>> +           : "=r" (__Res), "+m"(*__BitBase)
>> +           : "Ir"(__BitPos));
>> +  return __Res;
>> +}
>>  #ifdef __x86_64__
>>  static __inline__ unsigned char __attribute__((__always_inline__,
>> __nodebug__))
>>  _BitScanForward64(unsigned long *_Index, unsigned __int64 _Mask) {
>> @@ -621,6 +633,16 @@ _bittestandset64(__int64 *a, __int64 b)
>>    *a = *a | (1ll << b);
>>    return x;
>>  }
>> +static __inline__ unsigned char __attribute__((__always_inline__,
>> __nodebug__))
>> +_interlockedbittestandset64(__int64 volatile *__BitBase, __int64
>> __BitPos) {
>> +  unsigned char __Res;
>> +  __asm__ ("xor %0, %0\n"
>> +           "lock bts %2, %1\n"
>> +           "setc %0\n"
>> +           : "=r" (__Res), "+m"(*__BitBase)
>> +           : "Ir"(__BitPos));
>> +  return __Res;
>> +}
>>  #endif
>>
>> /*----------------------------------------------------------------------------*\
>>  |* Interlocked Exchange Add
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>



More information about the cfe-commits mailing list