aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@ost.ch>2025-12-10 17:20:14 +0100
committerFelix Morgner <felix.morgner@ost.ch>2025-12-10 17:21:42 +0100
commitf0c5ac3c8222d4d89b8e2d2a726427a7ec64e538 (patch)
treebd5bd98fd3cd1f41293688cf94ec57346f028a51
parentb9d445bf92725d79269becf978059e040519c00a (diff)
downloadteachos-f0c5ac3c8222d4d89b8e2d2a726427a7ec64e538.tar.xz
teachos-f0c5ac3c8222d4d89b8e2d2a726427a7ec64e538.zip
kstd: extract bitwise enum operations
-rw-r--r--.clang-format2
-rw-r--r--arch/x86_64/include/x86_64/cpu/impl/control_registers.hpp77
-rw-r--r--arch/x86_64/include/x86_64/cpu/impl/model_specific_register.hpp44
-rw-r--r--arch/x86_64/include/x86_64/memory/page_table.hpp31
-rw-r--r--libs/kstd/CMakeLists.txt2
-rw-r--r--libs/kstd/include/kstd/ext/bitfield_enum64
6 files changed, 110 insertions, 110 deletions
diff --git a/.clang-format b/.clang-format
index a47e396..e54cb03 100644
--- a/.clang-format
+++ b/.clang-format
@@ -61,6 +61,8 @@ IncludeCategories:
Priority: 110
- Regex: '"[[:alnum:]._\/]+\.hpp"'
Priority: 300
+ - Regex: '<kstd/[[:alnum:]._\/]+>'
+ Priority: 400
- Regex: '<[[:alnum:]._\/]+\.hpp>'
Priority: 600
- Regex: '<[[:alnum:]._]+(?!\.(h|hpp))>'
diff --git a/arch/x86_64/include/x86_64/cpu/impl/control_registers.hpp b/arch/x86_64/include/x86_64/cpu/impl/control_registers.hpp
index d892360..0c2254a 100644
--- a/arch/x86_64/include/x86_64/cpu/impl/control_registers.hpp
+++ b/arch/x86_64/include/x86_64/cpu/impl/control_registers.hpp
@@ -1,8 +1,12 @@
#ifndef TEACHOS_X86_64_CPU_IMPL_CONTROL_REGISTERS_HPP
#define TEACHOS_X86_64_CPU_IMPL_CONTROL_REGISTERS_HPP
+// IWYU pragma: private
+
#include "kapi/memory/address.hpp"
+#include <kstd/ext/bitfield_enum>
+
#include <cstdint>
#include <string_view>
#include <type_traits>
@@ -83,72 +87,12 @@ namespace teachos::cpu::x86_64
paging = 1uz << 31
};
- constexpr auto operator|(cr0_flags lhs, cr0_flags rhs) -> cr0_flags
- {
- return static_cast<cr0_flags>(static_cast<std::underlying_type_t<cr0_flags>>(lhs) |
- static_cast<std::underlying_type_t<cr0_flags>>(rhs));
- }
-
- constexpr auto operator|=(cr0_flags & lhs, cr0_flags rhs) -> cr0_flags &
- {
- lhs = lhs | rhs;
- return lhs;
- }
-
- constexpr auto operator&(cr0_flags lhs, cr0_flags rhs) -> cr0_flags
- {
- return static_cast<cr0_flags>(static_cast<std::underlying_type_t<cr0_flags>>(lhs) &
- static_cast<std::underlying_type_t<cr0_flags>>(rhs));
- }
-
- constexpr auto operator&=(cr0_flags & lhs, cr0_flags rhs) -> cr0_flags &
- {
- lhs = lhs & rhs;
- return lhs;
- }
-
- constexpr auto operator~(cr0_flags lhs) -> cr0_flags
- {
- // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
- return static_cast<cr0_flags>(~static_cast<std::underlying_type_t<cr0_flags>>(lhs));
- }
-
enum struct cr3_flags : std::uint64_t
{
page_level_write_through = 1uz << 0,
page_level_cache_disable = 1uz << 1,
};
- constexpr auto operator|(cr3_flags lhs, cr3_flags rhs) -> cr3_flags
- {
- return static_cast<cr3_flags>(static_cast<std::underlying_type_t<cr3_flags>>(lhs) |
- static_cast<std::underlying_type_t<cr3_flags>>(rhs));
- }
-
- constexpr auto operator|=(cr3_flags & lhs, cr3_flags rhs) -> cr3_flags &
- {
- lhs = lhs | rhs;
- return lhs;
- }
-
- constexpr auto operator&(cr3_flags lhs, cr3_flags rhs) -> cr3_flags
- {
- return static_cast<cr3_flags>(static_cast<std::underlying_type_t<cr3_flags>>(lhs) &
- static_cast<std::underlying_type_t<cr3_flags>>(rhs));
- }
-
- constexpr auto operator&=(cr3_flags & lhs, cr3_flags rhs) -> cr3_flags &
- {
- lhs = lhs & rhs;
- return lhs;
- }
-
- constexpr auto operator~(cr3_flags lhs) -> cr3_flags
- {
- // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
- return static_cast<cr3_flags>(~static_cast<std::underlying_type_t<cr3_flags>>(lhs));
- }
-
struct cr3_value
{
constexpr cr3_value() = default;
@@ -193,4 +137,17 @@ namespace teachos::cpu::x86_64
} // namespace teachos::cpu::x86_64
+namespace kstd::ext
+{
+ template<>
+ struct is_bitfield_enum<teachos::cpu::x86_64::impl::cr0_flags> : std::true_type
+ {
+ };
+
+ template<>
+ struct is_bitfield_enum<teachos::cpu::x86_64::impl::cr3_flags> : std::true_type
+ {
+ };
+} // namespace kstd::ext
+
#endif \ No newline at end of file
diff --git a/arch/x86_64/include/x86_64/cpu/impl/model_specific_register.hpp b/arch/x86_64/include/x86_64/cpu/impl/model_specific_register.hpp
index 8a41a8a..ff2c8ad 100644
--- a/arch/x86_64/include/x86_64/cpu/impl/model_specific_register.hpp
+++ b/arch/x86_64/include/x86_64/cpu/impl/model_specific_register.hpp
@@ -1,6 +1,10 @@
#ifndef TEACHOS_X86_64_CPU_IMPL_MODEL_SPECIFIC_REGISTER_HPP
#define TEACHOS_X86_64_CPU_IMPL_MODEL_SPECIFIC_REGISTER_HPP
+// IWYU pragma: private
+
+#include <kstd/ext/bitfield_enum>
+
#include <bit>
#include <cstdint>
#include <type_traits>
@@ -73,40 +77,20 @@ namespace teachos::cpu::x86_64
execute_disable_bit_enable = 1uz << 11,
};
- constexpr auto operator|(ia32_efer_flags lhs, ia32_efer_flags rhs) -> ia32_efer_flags
- {
- return static_cast<ia32_efer_flags>(static_cast<std::underlying_type_t<ia32_efer_flags>>(lhs) |
- static_cast<std::underlying_type_t<ia32_efer_flags>>(rhs));
- }
-
- constexpr auto operator|=(ia32_efer_flags & lhs, ia32_efer_flags rhs) -> ia32_efer_flags &
- {
- lhs = lhs | rhs;
- return lhs;
- }
-
- constexpr auto operator&(ia32_efer_flags lhs, ia32_efer_flags rhs) -> ia32_efer_flags
- {
- return static_cast<ia32_efer_flags>(static_cast<std::underlying_type_t<ia32_efer_flags>>(lhs) &
- static_cast<std::underlying_type_t<ia32_efer_flags>>(rhs));
- }
-
- constexpr auto operator&=(ia32_efer_flags & lhs, ia32_efer_flags rhs) -> ia32_efer_flags &
- {
- lhs = lhs & rhs;
- return lhs;
- }
-
- constexpr auto operator~(ia32_efer_flags lhs) -> ia32_efer_flags
- {
- // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
- return static_cast<ia32_efer_flags>(~static_cast<std::underlying_type_t<ia32_efer_flags>>(lhs));
- }
-
} // namespace impl
using i32_efer = impl::model_specific_register<impl::ia32_efer_number, impl::ia32_efer_flags>;
} // namespace teachos::cpu::x86_64
+namespace kstd::ext
+{
+
+ template<>
+ struct is_bitfield_enum<teachos::cpu::x86_64::impl::ia32_efer_flags> : std::true_type
+ {
+ };
+
+} // namespace kstd::ext
+
#endif \ No newline at end of file
diff --git a/arch/x86_64/include/x86_64/memory/page_table.hpp b/arch/x86_64/include/x86_64/memory/page_table.hpp
index ce34e23..22616e8 100644
--- a/arch/x86_64/include/x86_64/memory/page_table.hpp
+++ b/arch/x86_64/include/x86_64/memory/page_table.hpp
@@ -3,11 +3,14 @@
#include "kapi/memory.hpp"
+#include <kstd/ext/bitfield_enum>
+
#include <array>
#include <bit>
#include <cstddef>
#include <cstdint>
#include <optional>
+#include <type_traits>
#include <utility>
namespace teachos::memory::x86_64
@@ -87,26 +90,6 @@ namespace teachos::memory::x86_64
std::array<entry, entry_count> m_entries{};
};
- constexpr auto operator|(page_table::entry::flags lhs, page_table::entry::flags rhs) -> page_table::entry::flags
- {
- return std::bit_cast<page_table::entry::flags>(std::to_underlying(lhs) | std::to_underlying(rhs));
- }
-
- constexpr auto operator|=(page_table::entry::flags & lhs, page_table::entry::flags rhs) -> page_table::entry::flags &
- {
- return lhs = lhs | rhs;
- }
-
- constexpr auto operator&(page_table::entry::flags lhs, page_table::entry::flags rhs) -> page_table::entry::flags
- {
- return std::bit_cast<page_table::entry::flags>(std::to_underlying(lhs) & std::to_underlying(rhs));
- }
-
- constexpr auto operator~(page_table::entry::flags flags)
- {
- return std::bit_cast<page_table::entry::flags>(~std::to_underlying(flags));
- }
-
//! A recursively mapped page table.
template<std::size_t Level>
requires(Level > 0uz && Level < 5uz)
@@ -155,4 +138,12 @@ namespace teachos::memory::x86_64
} // namespace teachos::memory::x86_64
+namespace kstd::ext
+{
+ template<>
+ struct is_bitfield_enum<teachos::memory::x86_64::page_table::entry::flags> : std::true_type
+ {
+ };
+} // namespace kstd::ext
+
#endif \ No newline at end of file
diff --git a/libs/kstd/CMakeLists.txt b/libs/kstd/CMakeLists.txt
index e0c551c..d83e704 100644
--- a/libs/kstd/CMakeLists.txt
+++ b/libs/kstd/CMakeLists.txt
@@ -22,6 +22,8 @@ target_sources("kstd" PUBLIC
"include/kstd/bits/shared_ptr.hpp"
"include/kstd/bits/unique_ptr.hpp"
+ "include/kstd/ext/bitfield_enum"
+
"include/kstd/asm_ptr"
"include/kstd/memory"
"include/kstd/mutex"
diff --git a/libs/kstd/include/kstd/ext/bitfield_enum b/libs/kstd/include/kstd/ext/bitfield_enum
new file mode 100644
index 0000000..327af45
--- /dev/null
+++ b/libs/kstd/include/kstd/ext/bitfield_enum
@@ -0,0 +1,64 @@
+#ifndef KSTD_EXT_BITFIELD_ENUM_HPP
+#define KSTD_EXT_BITFIELD_ENUM_HPP
+
+#include <bit>
+#include <type_traits>
+#include <utility>
+
+namespace kstd::ext
+{
+
+ template<typename EnumType>
+ requires std::is_enum_v<EnumType>
+ struct is_bitfield_enum : std::false_type
+ {
+ };
+
+ template<typename EnumType>
+ concept bitfield_enum = is_bitfield_enum<EnumType>::value;
+
+}; // namespace kstd::ext
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator|(EnumType lhs, EnumType rhs) -> EnumType
+{
+ return std::bit_cast<EnumType>(std::to_underlying(lhs) | std::to_underlying(rhs));
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator|=(EnumType & lhs, EnumType rhs) -> EnumType &
+{
+ return lhs = lhs | rhs;
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator&(EnumType lhs, EnumType rhs) -> EnumType
+{
+ return std::bit_cast<EnumType>(std::to_underlying(lhs) & std::to_underlying(rhs));
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator&=(EnumType & lhs, EnumType rhs) -> EnumType &
+{
+ return lhs = lhs & rhs;
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator^(EnumType lhs, EnumType rhs) -> EnumType
+{
+ return std::bit_cast<EnumType>(std::to_underlying(lhs) ^ std::to_underlying(rhs));
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator^=(EnumType & lhs, EnumType rhs) -> EnumType &
+{
+ return lhs = lhs ^ rhs;
+}
+
+template<kstd::ext::bitfield_enum EnumType>
+constexpr auto operator~(EnumType lhs) -> EnumType
+{
+ return std::bit_cast<EnumType>(~std::to_underlying(lhs));
+}
+
+#endif \ No newline at end of file