| 
									
										
										
										
											2018-12-19 15:25:12 -05:00
										 |  |  | // Copyright 2018 yuzu emulator team
 | 
					
						
							|  |  |  | // Licensed under GPLv2 or any later version
 | 
					
						
							|  |  |  | // Refer to the license.txt file included.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 15:30:28 -08:00
										 |  |  | #include <bit>
 | 
					
						
							| 
									
										
										
										
											2018-12-19 15:25:12 -05:00
										 |  |  | #include <climits>
 | 
					
						
							|  |  |  | #include <cstddef>
 | 
					
						
							| 
									
										
										
										
											2021-11-20 14:46:19 +01:00
										 |  |  | #include <type_traits>
 | 
					
						
							| 
									
										
										
										
											2018-12-19 15:25:12 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "common/common_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Common { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Gets the size of a specified type T in bits.
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2020-08-14 09:38:45 -04:00
										 |  |  | [[nodiscard]] constexpr std::size_t BitSize() { | 
					
						
							| 
									
										
										
										
											2018-12-19 15:25:12 -05:00
										 |  |  |     return sizeof(T) * CHAR_BIT; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 MostSignificantBit32(const u32 value) { | 
					
						
							|  |  |  |     return 31U - static_cast<u32>(std::countl_zero(value)); | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 MostSignificantBit64(const u64 value) { | 
					
						
							|  |  |  |     return 63U - static_cast<u32>(std::countl_zero(value)); | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 Log2Floor32(const u32 value) { | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  |     return MostSignificantBit32(value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 Log2Floor64(const u64 value) { | 
					
						
							|  |  |  |     return MostSignificantBit64(value); | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 Log2Ceil32(const u32 value) { | 
					
						
							|  |  |  |     const u32 log2_f = Log2Floor32(value); | 
					
						
							|  |  |  |     return log2_f + static_cast<u32>((value ^ (1U << log2_f)) != 0U); | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 03:48:32 -05:00
										 |  |  | [[nodiscard]] constexpr u32 Log2Ceil64(const u64 value) { | 
					
						
							|  |  |  |     const u64 log2_f = Log2Floor64(value); | 
					
						
							|  |  |  |     return static_cast<u32>(log2_f + static_cast<u64>((value ^ (1ULL << log2_f)) != 0ULL)); | 
					
						
							| 
									
										
										
										
											2019-05-10 22:12:35 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-10 19:44:19 -05:00
										 |  |  | template <typename T> | 
					
						
							|  |  |  | requires std::is_unsigned_v<T> | 
					
						
							|  |  |  | [[nodiscard]] constexpr bool IsPow2(T value) { | 
					
						
							|  |  |  |     return std::has_single_bit(value); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-20 14:46:19 +01:00
										 |  |  | template <typename T> | 
					
						
							|  |  |  | requires std::is_integral_v<T> | 
					
						
							|  |  |  | [[nodiscard]] T NextPow2(T value) { | 
					
						
							|  |  |  |     return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-23 10:08:32 -08:00
										 |  |  | template <size_t bit_index, typename T> | 
					
						
							|  |  |  | requires std::is_integral_v<T> | 
					
						
							|  |  |  | [[nodiscard]] constexpr bool Bit(const T value) { | 
					
						
							|  |  |  |     static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T"); | 
					
						
							|  |  |  |     return ((value >> bit_index) & T(1)) == T(1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 15:25:12 -05:00
										 |  |  | } // namespace Common
 |