Common: Add intrin.h

This commit is contained in:
Stenzek
2023-10-01 14:12:25 +10:00
parent b1bb33a566
commit 01e505ec8b
26 changed files with 235 additions and 206 deletions

View File

@ -180,130 +180,6 @@ static constexpr u32 HOST_PAGE_MASK = HOST_PAGE_SIZE - 1;
static constexpr u32 HOST_PAGE_SHIFT = 12;
#endif
// Zero-extending helper
template<typename TReturn, typename TValue>
ALWAYS_INLINE constexpr TReturn ZeroExtend(TValue value)
{
return static_cast<TReturn>(static_cast<typename std::make_unsigned<TReturn>::type>(
static_cast<typename std::make_unsigned<TValue>::type>(value)));
}
// Sign-extending helper
template<typename TReturn, typename TValue>
ALWAYS_INLINE constexpr TReturn SignExtend(TValue value)
{
return static_cast<TReturn>(
static_cast<typename std::make_signed<TReturn>::type>(static_cast<typename std::make_signed<TValue>::type>(value)));
}
// Type-specific helpers
template<typename TValue>
ALWAYS_INLINE constexpr u16 ZeroExtend16(TValue value)
{
return ZeroExtend<u16, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u32 ZeroExtend32(TValue value)
{
return ZeroExtend<u32, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u64 ZeroExtend64(TValue value)
{
return ZeroExtend<u64, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u16 SignExtend16(TValue value)
{
return SignExtend<u16, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u32 SignExtend32(TValue value)
{
return SignExtend<u32, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u64 SignExtend64(TValue value)
{
return SignExtend<u64, TValue>(value);
}
template<typename TValue>
ALWAYS_INLINE constexpr u8 Truncate8(TValue value)
{
return static_cast<u8>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
}
template<typename TValue>
ALWAYS_INLINE constexpr u16 Truncate16(TValue value)
{
return static_cast<u16>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
}
template<typename TValue>
ALWAYS_INLINE constexpr u32 Truncate32(TValue value)
{
return static_cast<u32>(static_cast<typename std::make_unsigned<decltype(value)>::type>(value));
}
// BCD helpers
ALWAYS_INLINE constexpr u8 BinaryToBCD(u8 value)
{
return ((value / 10) << 4) + (value % 10);
}
ALWAYS_INLINE constexpr u8 PackedBCDToBinary(u8 value)
{
return ((value >> 4) * 10) + (value % 16);
}
ALWAYS_INLINE constexpr u8 IsValidBCDDigit(u8 digit)
{
return (digit <= 9);
}
ALWAYS_INLINE constexpr u8 IsValidPackedBCD(u8 value)
{
return IsValidBCDDigit(value & 0x0F) && IsValidBCDDigit(value >> 4);
}
// Boolean to integer
ALWAYS_INLINE constexpr u8 BoolToUInt8(bool value)
{
return static_cast<u8>(value);
}
ALWAYS_INLINE constexpr u16 BoolToUInt16(bool value)
{
return static_cast<u16>(value);
}
ALWAYS_INLINE constexpr u32 BoolToUInt32(bool value)
{
return static_cast<u32>(value);
}
ALWAYS_INLINE constexpr u64 BoolToUInt64(bool value)
{
return static_cast<u64>(value);
}
// Integer to boolean
template<typename TValue>
ALWAYS_INLINE constexpr bool ConvertToBool(TValue value)
{
return static_cast<bool>(value);
}
// Unsafe integer to boolean
template<typename TValue>
ALWAYS_INLINE bool ConvertToBoolUnchecked(TValue value)
{
// static_assert(sizeof(uint8) == sizeof(bool));
bool ret;
std::memcpy(&ret, &value, sizeof(bool));
return ret;
}
// Generic sign extension
template<int NBITS, typename T>
ALWAYS_INLINE constexpr T SignExtendN(T value)
{
// http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
constexpr int shift = 8 * sizeof(T) - NBITS;
return static_cast<T>((static_cast<std::make_signed_t<T>>(value) << shift) >> shift);
}
// Enum class bitwise operators
#define IMPLEMENT_ENUM_CLASS_BITWISE_OPERATORS(type_) \
ALWAYS_INLINE constexpr type_ operator&(type_ lhs, type_ rhs) \