mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-12 17:19:10 +01:00
0a6f0dfb74
This attempts to make some bit arithmetic more self-documenting and also make it easier during review to identify potential off-by-one errors by making it possible to just specify which bits are being extracted. Functions both support the case where bits being extracted can vary and fixed bit extraction. In the case the bits are fixed, compile-time asserts are present to prevent accidental API usage at compile-time. e.g. Instead of shifting and masking to get bits 10 to 15, Common::ExtractBits<10, 15>(value) can just be done instead.
60 lines
1.9 KiB
C++
60 lines
1.9 KiB
C++
// Copyright 2017 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "Common/BitUtils.h"
|
|
#include "Common/CommonTypes.h"
|
|
|
|
TEST(BitUtils, BitSize)
|
|
{
|
|
EXPECT_EQ(Common::BitSize<s8>(), 8);
|
|
EXPECT_EQ(Common::BitSize<s16>(), 16);
|
|
EXPECT_EQ(Common::BitSize<s32>(), 32);
|
|
EXPECT_EQ(Common::BitSize<s64>(), 64);
|
|
|
|
EXPECT_EQ(Common::BitSize<u8>(), 8);
|
|
EXPECT_EQ(Common::BitSize<u16>(), 16);
|
|
EXPECT_EQ(Common::BitSize<u32>(), 32);
|
|
EXPECT_EQ(Common::BitSize<u64>(), 64);
|
|
}
|
|
|
|
TEST(BitUtils, ExtractBit)
|
|
{
|
|
constexpr s32 zero = 0;
|
|
EXPECT_EQ(Common::ExtractBit<0>(zero), 0);
|
|
|
|
constexpr s32 one = 1;
|
|
EXPECT_EQ(Common::ExtractBit<0>(one), 1);
|
|
|
|
constexpr s32 negative_one = -1;
|
|
EXPECT_EQ(Common::ExtractBit<31>(negative_one), 1);
|
|
|
|
constexpr s32 one_hundred_twenty_eight = 0b10000000;
|
|
EXPECT_EQ(Common::ExtractBit<7>(one_hundred_twenty_eight), 1);
|
|
}
|
|
|
|
TEST(BitUtils, ExtractBits)
|
|
{
|
|
// Note: Parenthesizing is necessary to prevent the macros from
|
|
// mangling the template function usages.
|
|
|
|
constexpr s32 two_hundred_four_signed = 0b0011001100;
|
|
EXPECT_EQ((Common::ExtractBits<2, 3>(two_hundred_four_signed)), 3);
|
|
EXPECT_EQ((Common::ExtractBits<2, 7>(two_hundred_four_signed)), 51);
|
|
EXPECT_EQ((Common::ExtractBits<3, 6>(two_hundred_four_signed)), 9);
|
|
|
|
constexpr u32 two_hundred_four_unsigned = 0b0011001100;
|
|
EXPECT_EQ((Common::ExtractBits<2, 3>(two_hundred_four_unsigned)), 3);
|
|
EXPECT_EQ((Common::ExtractBits<2, 7>(two_hundred_four_unsigned)), 51);
|
|
EXPECT_EQ((Common::ExtractBits<3, 6>(two_hundred_four_unsigned)), 9);
|
|
|
|
// Ensure bit extraction remains sign-independent even when signed types are used.
|
|
constexpr s32 negative_one = -1;
|
|
EXPECT_EQ((Common::ExtractBits<0, 31>(negative_one)), 0xFFFFFFFFU);
|
|
|
|
// Ensure bit extraction with type overriding works as expected
|
|
EXPECT_EQ((Common::ExtractBits<0, 31, s32, s32>(negative_one)), -1);
|
|
}
|