[PATCH] D33616: [MS] Fix _bittest* intrinsics for values bigger than 31
Reid Kleckner via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri May 26 16:56:29 PDT 2017
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;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33616.100502.patch
Type: text/x-patch
Size: 3546 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170526/9876a676/attachment.bin>
More information about the cfe-commits
mailing list