CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Common/BitSet.h
Views: 1401
// This file is under the public domain.12#pragma once34#include "ppsspp_config.h"5#include <cstdint>6#include <cstdlib> // for byte swapping7#include <cstddef>8#include "CommonTypes.h"910// TODO: ARM has an intrinsic for the RBIT instruction in some compilers, __rbit.11inline u32 ReverseBits32(u32 v) {12// http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel13// swap odd and even bits14v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);15// swap consecutive pairs16v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);17// swap nibbles ...18v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);19// swap bytes20v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);21// swap 2-byte long pairs22v = (v >> 16) | (v << 16);23return v;24}2526#ifdef _WIN3227#include <intrin.h>28template <typename T>29inline int CountSetBits(T v) {30// from https://graphics.stanford.edu/~seander/bithacks.html31// GCC has this built in, but MSVC's intrinsic will only emit the actual32// POPCNT instruction, which we're not depending on33v = v - ((v >> 1) & (T)~(T)0/3);34v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);35v = (v + (v >> 4)) & (T)~(T)0/255*15;36return (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * 8;37}38inline int LeastSignificantSetBit(u32 val)39{40unsigned long index;41_BitScanForward(&index, val);42return (int)index;43}44#if PPSSPP_ARCH(AMD64)45inline int LeastSignificantSetBit(u64 val)46{47unsigned long index;48_BitScanForward64(&index, val);49return (int)index;50}5152#endif53#else54inline int CountSetBits(u32 val) { return __builtin_popcount(val); }55inline int CountSetBits(u64 val) { return __builtin_popcountll(val); }56inline int LeastSignificantSetBit(u32 val) { return __builtin_ctz(val); }57inline int LeastSignificantSetBit(u64 val) { return __builtin_ctzll(val); }58#endif5960// Byteswapping61// Just in case this has been defined by platform62#undef swap1663#undef swap3264#undef swap646566#ifdef _WIN3267inline uint16_t swap16(uint16_t _data) { return _byteswap_ushort(_data); }68inline uint32_t swap32(uint32_t _data) { return _byteswap_ulong(_data); }69inline uint64_t swap64(uint64_t _data) { return _byteswap_uint64(_data); }70#elif defined(__GNUC__)71inline uint16_t swap16(uint16_t _data) { return __builtin_bswap16(_data); }72inline uint32_t swap32(uint32_t _data) { return __builtin_bswap32(_data); }73inline uint64_t swap64(uint64_t _data) { return __builtin_bswap64(_data); }74#else75// Slow generic implementation. Hopefully this never hits76inline uint16_t swap16(uint16_t data) { return (data >> 8) | (data << 8); }77inline uint32_t swap32(uint32_t data) { return (swap16(data) << 16) | swap16(data >> 16); }78inline uint64_t swap64(uint64_t data) { return ((uint64_t)swap32(data) << 32) | swap32(data >> 32); }79#endif8081inline uint16_t swap16(const uint8_t* _pData) { return swap16(*(const uint16_t*)_pData); }82inline uint32_t swap32(const uint8_t* _pData) { return swap32(*(const uint32_t*)_pData); }83inline uint64_t swap64(const uint8_t* _pData) { return swap64(*(const uint64_t*)_pData); }848586