rnk created this revision.

These intrinsics are supposed to select to BT, BTS, etc instructions.
Those instructions actually perform a bitwise array indexing memory
operation that LLVM doesn't currently expose.  This change implements
the shifting and array indexing in plain C.

Fixes PR33188

If we ever fix PR19164, then the array indexing should be pattern
matched to BT and BTS memory instructions as appropriate.


https://reviews.llvm.org/D33616

Files:
  clang/lib/Headers/intrin.h


Index: clang/lib/Headers/intrin.h
===================================================================
--- clang/lib/Headers/intrin.h
+++ clang/lib/Headers/intrin.h
@@ -342,68 +342,92 @@
 
\*----------------------------------------------------------------------------*/
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittest(long const *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   return (*_BitBase >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandcomplement(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase ^ (1 << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandreset(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase & ~(1 << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandset(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase | (1 << _BitPos);
   return _Res;
 }
 #if defined(__arm__) || defined(__aarch64__)
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_acq(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_ACQUIRE);
   return (_PrevVal >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_nf(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_RELAXED);
   return (_PrevVal >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_rel(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_RELEASE);
   return (_PrevVal >> _BitPos) & 1;
 }
 #endif
 #ifdef __x86_64__
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittest64(__int64 const *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   return (*_BitBase >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandcomplement64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase ^ (1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandreset64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase & ~(1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandset64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase | (1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset64(__int64 volatile *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   long long _PrevVal =
       __atomic_fetch_or(_BitBase, 1ll << _BitPos, __ATOMIC_SEQ_CST);
   return (_PrevVal >> _BitPos) & 1;


Index: clang/lib/Headers/intrin.h
===================================================================
--- clang/lib/Headers/intrin.h
+++ clang/lib/Headers/intrin.h
@@ -342,68 +342,92 @@
 \*----------------------------------------------------------------------------*/
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittest(long const *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   return (*_BitBase >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandcomplement(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase ^ (1 << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandreset(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase & ~(1 << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandset(long *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase | (1 << _BitPos);
   return _Res;
 }
 #if defined(__arm__) || defined(__aarch64__)
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_acq(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_ACQUIRE);
   return (_PrevVal >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_nf(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_RELAXED);
   return (_PrevVal >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset_rel(long volatile *_BitBase, long _BitPos) {
+  _BitBase += (_BitPos / 32);
+  _BitPos %= 32;
   long _PrevVal = __atomic_fetch_or(_BitBase, 1l << _BitPos, __ATOMIC_RELEASE);
   return (_PrevVal >> _BitPos) & 1;
 }
 #endif
 #ifdef __x86_64__
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittest64(__int64 const *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   return (*_BitBase >> _BitPos) & 1;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandcomplement64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase ^ (1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandreset64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase & ~(1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _bittestandset64(__int64 *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   unsigned char _Res = (*_BitBase >> _BitPos) & 1;
   *_BitBase = *_BitBase | (1ll << _BitPos);
   return _Res;
 }
 static __inline__ unsigned char __DEFAULT_FN_ATTRS
 _interlockedbittestandset64(__int64 volatile *_BitBase, __int64 _BitPos) {
+  _BitBase += (_BitPos / 64);
+  _BitPos %= 64;
   long long _PrevVal =
       __atomic_fetch_or(_BitBase, 1ll << _BitPos, __ATOMIC_SEQ_CST);
   return (_PrevVal >> _BitPos) & 1;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to