Kaynağa Gözat

feat(libstdc++): add bit_cast

greatbridf 1 yıl önce
ebeveyn
işleme
9fcf1ba7ba

+ 14 - 0
gblibstdc++/include/bit

@@ -0,0 +1,14 @@
+#ifndef __GBLIBCPP_BIT__
+#define __GBLIBCPP_BIT__
+
+namespace std {
+
+template <typename To, typename From>
+constexpr To bit_cast(const From& from) noexcept
+{
+    return __builtin_bit_cast(To, from);
+}
+
+} // namespace std
+
+#endif

+ 2 - 0
gblibstdc++/include/cstddef

@@ -10,6 +10,8 @@ using nullptr_t = decltype(nullptr);
 
 using size_t = __SIZE_TYPE__;
 
+enum class byte : unsigned char {};
+
 }; // namespace std
 
 #endif

+ 19 - 13
gblibstdc++/include/memory

@@ -7,22 +7,28 @@
 namespace std {
 
 template <typename T>
-constexpr enable_if_t<is_function_v<remove_reference_t<T>>, T*>
-addressof(T& arg) noexcept
+constexpr T* addressof(T& arg) noexcept
 {
-    return &arg;
+    return __builtin_addressof(arg);
 }
 
-template <typename T>
-constexpr enable_if_t<!is_function_v<remove_reference_t<T>>, T*>
-addressof(T& arg) noexcept
-{
-    return reinterpret_cast<T*>(
-        &const_cast<char&>(
-            reinterpret_cast<const volatile char&>(arg)
-        )
-    );
-}
+// template <typename T>
+// constexpr enable_if_t<is_function_v<remove_reference_t<T>>, T*>
+// addressof(T& arg) noexcept
+// {
+//     return &arg;
+// }
+
+// template <typename T>
+// constexpr enable_if_t<!is_function_v<remove_reference_t<T>>, T*>
+// addressof(T& arg) noexcept
+// {
+//     return reinterpret_cast<T*>(
+//         &const_cast<char&>(
+//             reinterpret_cast<const volatile char&>(arg)
+//         )
+//     );
+// }
 
 template <typename T>
 const T* addressof(const T&&) = delete;

+ 42 - 22
include/kernel/mm.hpp

@@ -1,5 +1,7 @@
 #pragma once
 
+#include <bit>
+#include <cstddef>
 #include <utility>
 
 #include <kernel/mem.h>
@@ -56,7 +58,7 @@ class mm_list;
 } // namespace kernel
 
 template <uint32_t base, uint32_t expo>
-inline constexpr uint32_t pow()
+constexpr uint32_t pow()
 {
     if constexpr (expo == 0)
         return 1;
@@ -68,15 +70,38 @@ inline constexpr uint32_t pow()
         return pow<base, expo / 2>() * pow<base, expo / 2 + 1>();
 }
 
-template <int n>
-inline constexpr uint32_t align_down(uint32_t v)
+template <int N>
+constexpr uint32_t align_down(uint32_t v)
 {
-    return v & ~(pow<2, n>() - 1);
+    return v & ~(pow<2, N>() - 1);
 }
-template <int n>
-inline constexpr uint32_t align_up(uint32_t v)
+template <int N>
+constexpr void* align_down(void* v)
 {
-    return align_down<n>(v + pow<2, n>() - 1);
+    return std::bit_cast<void*>(align_down<N>(std::bit_cast<uint32_t>(v)));
+}
+template <int N>
+constexpr uint32_t align_up(uint32_t v)
+{
+    return align_down<N>(v + pow<2, N>() - 1);
+}
+template <int N>
+constexpr void* align_up(void* v)
+{
+    return std::bit_cast<void*>(align_up<N>(std::bit_cast<uint32_t>(v)));
+}
+
+constexpr size_t vptrdiff(void* p1, void* p2)
+{
+    auto* _p1 = static_cast<std::byte*>(p1);
+    auto* _p2 = static_cast<std::byte*>(p2);
+    return _p1 - _p2;
+}
+
+constexpr void* vptradd(void* p, std::size_t off)
+{
+    auto* _p = static_cast<std::byte*>(p);
+    return _p + off;
 }
 
 void dealloc_pd(page_t pd);
@@ -112,9 +137,9 @@ public:
         return (char*)this->start + this->pgs->size() * PAGE_SIZE;
     }
 
-    inline bool is_kernel_space(void) const
+    constexpr bool is_kernel_space(void) const
     {
-        return this->start >= (void*)0xc0000000;
+        return this->start >= std::bit_cast<void*>(0xc0000000);
     }
 
     constexpr bool is_avail(void* start, void* end) const
@@ -130,7 +155,7 @@ public:
 
 namespace kernel {
 
-uint8_t* pmap(page_t pg);
+void* pmap(page_t pg);
 void pfree(page_t pg);
 
 class paccess : public types::non_copyable {
@@ -304,11 +329,10 @@ public:
         return this->end();
     }
 
-    bool is_avail(void* start, size_t len)
+    constexpr bool is_avail(void* start, size_t len)
     {
-        start = (void*)align_down<12>((uint32_t)start);
-        len = align_up<12>((uint32_t)start + len)
-            - (uint32_t)start;
+        start = align_down<12>(start);
+        len = vptrdiff(align_up<12>(vptradd(start, len)), start);
         for (const auto& area : *this) {
             if (!area.is_avail(start, (char*)start + len))
                 return false;
@@ -325,10 +349,6 @@ inline kernel::mm_list* kernel_mms;
 inline page empty_page;
 // --------------------------------
 
-inline constexpr size_t vptrdiff(void* p1, void* p2)
-{
-    return (uint8_t*)p1 - (uint8_t*)p2;
-}
 // inline constexpr page* lto_page(mm* mm_area, void* l_ptr)
 // {
 //     size_t offset = vptrdiff(l_ptr, mm_area->start);
@@ -350,13 +370,13 @@ inline constexpr size_t vptrdiff(void* p1, void* p2)
 // {
 //     return p << 12;
 // }
-inline size_t v_to_pdi(void* addr)
+constexpr size_t v_to_pdi(void* addr)
 {
-    return (uint32_t)addr >> 22;
+    return std::bit_cast<uint32_t>(addr) >> 22;
 }
-inline size_t v_to_pti(void* addr)
+constexpr size_t v_to_pti(void* addr)
 {
-    return ((uint32_t)addr >> 12) & 0x3ff;
+    return (std::bit_cast<uint32_t>(addr) >> 12) & 0x3ff;
 }
 // inline constexpr pte_t* to_pte(pt_t pt, page_t pg)
 // {

+ 2 - 1
include/types/hash_map.hpp

@@ -1,4 +1,5 @@
 #pragma once
+#include <bit>
 #include <utility>
 #include <type_traits>
 
@@ -49,7 +50,7 @@ struct linux_hasher<T,
     std::enable_if_t<std::is_pointer_v<T> && !is_c_string_v<T>>> {
     static inline constexpr hash_t hash(T val, uint32_t bits)
     {
-        return hash32(reinterpret_cast<uint32_t>(val), bits);
+        return hash32(std::bit_cast<uint32_t>(val), bits);
     }
 };
 

+ 14 - 6
src/kernel/mem.cpp

@@ -1,3 +1,5 @@
+#include <cstddef>
+
 #include <asm/port_io.h>
 #include <asm/sys.h>
 #include <assert.h>
@@ -371,7 +373,7 @@ void create_segment_descriptor(
 namespace __physmapper {
 struct mapped_area {
     size_t ref;
-    uint8_t* ptr;
+    void* ptr;
 };
 
 static types::hash_map<page_t, mapped_area,
@@ -380,8 +382,11 @@ static types::hash_map<page_t, mapped_area,
 static uint8_t freebm[0x400 / 8];
 } // namespace __physmapper
 
-uint8_t* kernel::pmap(page_t pg)
+void* kernel::pmap(page_t pg)
 {
+    auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
+    auto* const mapped_start = std::bit_cast<void*>(0xff000000);
+
     auto iter = __physmapper::mapped.find(pg);
     if (iter) {
         ++iter->value.ref;
@@ -390,11 +395,11 @@ uint8_t* kernel::pmap(page_t pg)
 
     for (int i = 2; i < 0x400; ++i) {
         if (bm_test(__physmapper::freebm, i) == 0) {
-            auto* pte = (pte_t*)(0xff001000) + i;
+            auto* pte = pmap_pt + i;
             pte->v = 0x3;
             pte->in.page = pg;
 
-            uint8_t* ptr = (uint8_t*)0xff000000 + 0x1000 * i;
+            void* ptr = vptradd(mapped_start, 0x1000 * i);
             invalidate_tlb(ptr);
 
             bm_set(__physmapper::freebm, i);
@@ -408,6 +413,9 @@ uint8_t* kernel::pmap(page_t pg)
 }
 void kernel::pfree(page_t pg)
 {
+    auto* const pmap_pt = std::bit_cast<pte_t*>(0xff001000);
+    auto* const mapped_start = std::bit_cast<void*>(0xff000000);
+
     auto iter = __physmapper::mapped.find(pg);
     if (!iter)
         return;
@@ -417,10 +425,10 @@ void kernel::pfree(page_t pg)
         return;
     }
 
-    int i = (uint32_t)iter->value.ptr - 0xff000000;
+    int i = vptrdiff(iter->value.ptr, mapped_start);
     i /= 0x1000;
 
-    auto* pte = (pte_t*)(0xff001000) + i;
+    auto* pte = pmap_pt + i;
     pte->v = 0;
     invalidate_tlb(iter->value.ptr);
 

+ 4 - 2
src/kernel/vfs.cpp

@@ -1,3 +1,5 @@
+#include <bit>
+
 #include <assert.h>
 #include <kernel/errno.h>
 #include <kernel/mem.h>
@@ -247,9 +249,9 @@ private:
     {
         return static_cast<fdata_t*>(data);
     }
-    static inline ptr_t as_val(void* data)
+    static constexpr ptr_t as_val(void* data)
     {
-        return reinterpret_cast<ptr_t>(data);
+        return std::bit_cast<ptr_t>(data);
     }
     inline void* _getdata(fs::ino_t ino) const
     {