| 
									
										
										
										
											2017-01-13 17:18:10 -05:00
										 |  |  | // 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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-24 17:08:19 -07:00
										 |  |  |   EXPECT_EQ(Common::BitSize<s8>(), 8u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<s16>(), 16u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<s32>(), 32u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<s64>(), 64u); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<u8>(), 8u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<u16>(), 16u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<u32>(), 32u); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::BitSize<u64>(), 64u); | 
					
						
							| 
									
										
										
										
											2017-01-13 17:18:10 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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; | 
					
						
							| 
									
										
										
										
											2017-03-24 17:08:19 -07:00
										 |  |  |   EXPECT_EQ((Common::ExtractBits<2, 3>(two_hundred_four_signed)), 3u); | 
					
						
							|  |  |  |   EXPECT_EQ((Common::ExtractBits<2, 7>(two_hundred_four_signed)), 51u); | 
					
						
							|  |  |  |   EXPECT_EQ((Common::ExtractBits<3, 6>(two_hundred_four_signed)), 9u); | 
					
						
							| 
									
										
										
										
											2017-01-13 17:18:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constexpr u32 two_hundred_four_unsigned = 0b0011001100; | 
					
						
							| 
									
										
										
										
											2017-03-24 17:08:19 -07:00
										 |  |  |   EXPECT_EQ((Common::ExtractBits<2, 3>(two_hundred_four_unsigned)), 3u); | 
					
						
							|  |  |  |   EXPECT_EQ((Common::ExtractBits<2, 7>(two_hundred_four_unsigned)), 51u); | 
					
						
							|  |  |  |   EXPECT_EQ((Common::ExtractBits<3, 6>(two_hundred_four_unsigned)), 9u); | 
					
						
							| 
									
										
										
										
											2017-01-13 17:18:10 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // 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); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-31 17:30:00 -04:00
										 |  |  | TEST(BitUtils, RotateLeft) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 0), 0xF0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 4), 0x0F0F0F0F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0, 8), 0xF0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 0), 0xF0F0F0F0F0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 4), 0x0F0F0F0F0F0F0F0F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF0F0F0F0F0F0F0F0, 8), 0xF0F0F0F0F0F0F0F0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 1), 0xE3E3E3E3); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 2), 0xC7C7C7C7); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 3), 0x8F8F8F8F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1, 4), 0x1F1F1F1F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 1), 0xE3E3E3E3E3E3E3E3); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 2), 0xC7C7C7C7C7C7C7C7); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 3), 0x8F8F8F8F8F8F8F8F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateLeft(0xF1F1F1F1F1F1F1F1, 4), 0x1F1F1F1F1F1F1F1F); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TEST(BitUtils, RotateRight) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 0), 0xF0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 4), 0x0F0F0F0F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0, 8), 0xF0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 0), 0xF0F0F0F0F0F0F0F0); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 4), 0x0F0F0F0F0F0F0F0F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF0F0F0F0F0F0F0F0, 8), 0xF0F0F0F0F0F0F0F0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 1), 0xF8F8F8F8); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 2), 0x7C7C7C7C); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 3), 0x3E3E3E3E); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1, 4), 0x1F1F1F1F); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 1), 0xF8F8F8F8F8F8F8F8); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 2), 0x7C7C7C7C7C7C7C7C); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 3), 0x3E3E3E3E3E3E3E3E); | 
					
						
							|  |  |  |   EXPECT_EQ(Common::RotateRight(0xF1F1F1F1F1F1F1F1, 4), 0x1F1F1F1F1F1F1F1F); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  | TEST(BitUtils, IsValidLowMask) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask(0b0u)); | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask(0b1u)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask(0b10u)); | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask(0b11u)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask(0b1110u)); | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask(0b1111u)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask(0b10000u)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask(0b101111u)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask((u8)~0b0)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u8)(~0b0 - 1))); | 
					
						
							| 
									
										
										
										
											2017-08-13 19:02:41 -07:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u8) ~(0b10000))); | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u8)(~((u8)(~0b0) >> 1) | 0b1111))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask((u16)~0b0)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u16)(~0b0 - 1))); | 
					
						
							| 
									
										
										
										
											2017-08-13 19:02:41 -07:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u16) ~(0b10000))); | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u16)(~((u16)(~0b0) >> 1) | 0b1111))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask((u32)~0b0)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u32)(~0b0 - 1))); | 
					
						
							| 
									
										
										
										
											2017-08-13 19:02:41 -07:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u32) ~(0b10000))); | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u32)(~((u32)(~0b0) >> 1) | 0b1111))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   EXPECT_TRUE(Common::IsValidLowMask((u64)~0b0)); | 
					
						
							|  |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u64)(~0b0 - 1))); | 
					
						
							| 
									
										
										
										
											2017-08-13 19:02:41 -07:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u64) ~(0b10000))); | 
					
						
							| 
									
										
										
										
											2017-06-22 12:36:54 +02:00
										 |  |  |   EXPECT_FALSE(Common::IsValidLowMask((u64)(~((u64)(~0b0) >> 1) | 0b1111))); | 
					
						
							|  |  |  | } |