Le code suivant appelle les fonctions intégrées pour clz/ctz dans GCC et, sur d'autres systèmes, a des versions C. Évidemment, les versions C sont un peu sous-optimales si le système a une instruction clz/ctz intégrée, comme x86 et ARM.Comment utiliser les intrinsèques MSVC pour obtenir l'équivalent de ce code GCC?
#ifdef __GNUC__
#define clz(x) __builtin_clz(x)
#define ctz(x) __builtin_ctz(x)
#else
static uint32_t ALWAYS_INLINE popcnt(uint32_t x)
{
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz(uint32_t x)
{
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz(uint32_t x)
{
return popcnt((x & -x) - 1);
}
#endif
Quelles fonctions dois-je appeler, en-têtes qui dois-je inclure, etc pour ajouter un ifdef approprié pour MSVC ici? J'ai déjà regardé this page, mais je ne suis pas tout à fait sûr à quoi sert le #pragma (est-il nécessaire?) Et quelles restrictions il met sur les exigences de version MSVC pour la compilation. En tant que personne qui n'utilise pas vraiment MSVC, je ne sais pas non plus si ces intrinsèques ont des équivalents C sur d'autres architectures, ou si je dois #ifdef x86/x86_64 aussi bien quand # les définir.
La page que vous faites référence ci-dessus fait référence à une fonction qui fait partie du moteur d'exécution .NET, vous essayez de construire votre programme pour .NET ou comme un exécutable Windows natif ? –
C'est un exécutable Windows natif - une partie de la raison pour laquelle je demande est que j'ai trouvé plutôt difficile de trouver des pages de documentation Microsoft qui parlent réellement de C ces jours-ci. –
Implémentation de Libcxx https://github.com/llvm-mirror/libcxx/blob/9dcbb46826fd4d29b1485f25e8986d36019a6dca/include/support/win32/support.h#L106-L182 – KindDragon