~satchmo/libvmm

8d5568646520d4d8c20e7ab34c57436404aadfcd — Jason Phan 3 years ago 0709f78
memory: Add MemoryRegionAddress and change return type of the align method
M tests/memory/address.cpp => tests/memory/address.cpp +4 -2
@@ 2,12 2,13 @@

#include <catch2/catch.hpp>

#include "vmm/memory.hpp"
#include "vmm/memory/memory.hpp"

class TestAddress : public vmm::memory::Address<TestAddress, uint64_t>
{
    using value_type = TestAddress;
    using size_type = uint64_t;
    using reference = value_type&;
    using const_reference = const value_type&;

    private:


@@ 27,10 28,11 @@ class TestAddress : public vmm::memory::Address<TestAddress, uint64_t>
        auto operator==(const_reference addr) const noexcept -> bool { return m_addr == addr.data(); }
        auto operator!=(const_reference addr) const noexcept -> bool { return m_addr != addr.data(); }

        auto align(const size_type alignment) noexcept -> void override
        auto align(const size_type alignment) noexcept -> reference override
		{
            const auto mask = alignment - 1;
            m_addr = (*this + mask) & ~mask;
            return *this;
		}
};


M vmm/memory/detail/address.hpp => vmm/memory/detail/address.hpp +1 -1
@@ 41,7 41,7 @@ class Address
        virtual auto operator-(const Concrete&) const noexcept -> Concrete = 0;

        // Aligns the address to a power of 2.
        virtual auto align(const Size) noexcept -> void = 0;
        virtual auto align(const Size) noexcept -> Concrete& = 0;
};

//template<typename Derived>

M vmm/memory/detail/guest.cpp => vmm/memory/detail/guest.cpp +44 -1
@@ 38,10 38,53 @@ auto GuestAddress::operator-(const_reference addr) const noexcept -> value_type
    return *this - addr.data();
}

auto GuestAddress::align(const size_type alignment) noexcept -> void
auto GuestAddress::align(const size_type alignment) noexcept -> reference
{
    const auto mask = alignment - 1;
    m_addr = (*this + mask) & ~mask;
    return *this;
}

auto MemoryRegionAddress::data() const noexcept -> size_type
{
    return m_addr;
}

auto MemoryRegionAddress::operator&(const size_type mask) const noexcept -> size_type
{
    return m_addr & mask;
}

auto MemoryRegionAddress::operator|(const size_type mask) const noexcept -> size_type
{
    return m_addr | mask;
}

auto MemoryRegionAddress::operator+(const size_type val) const noexcept -> value_type
{
    return MemoryRegionAddress{m_addr + val};
}

auto MemoryRegionAddress::operator+(const_reference addr) const noexcept -> value_type
{
    return *this + addr.data();
}

auto MemoryRegionAddress::operator-(const size_type val) const noexcept -> value_type
{
    return MemoryRegionAddress{m_addr - val};
}

auto MemoryRegionAddress::operator-(const_reference addr) const noexcept -> value_type
{
    return *this - addr.data();
}

auto MemoryRegionAddress::align(const size_type alignment) noexcept -> reference
{
    const auto mask = alignment - 1;
    m_addr = (*this + mask) & ~mask;
    return *this;
}

}  // vmm::memory::detail

M vmm/memory/detail/guest.hpp => vmm/memory/detail/guest.hpp +40 -1
@@ 22,6 22,7 @@ class GuestAddress : public Address<GuestAddress, uint64_t>
{
    using value_type = GuestAddress;
    using size_type = uint64_t;
    using reference = value_type&;
    using const_reference = const value_type&;

    private:


@@ 51,7 52,45 @@ class GuestAddress : public Address<GuestAddress, uint64_t>
        auto operator-(const_reference addr) const noexcept -> value_type override;

        // Aligns the address to a power of 2.
        auto align(const size_type alignment) noexcept -> void override;
        auto align(const size_type alignment) noexcept -> reference override;
};

// An offset into a memory region.
class MemoryRegionAddress : public Address<MemoryRegionAddress, uint64_t>
{
    using value_type = MemoryRegionAddress;
    using size_type = uint64_t;
    using reference = value_type&;
    using const_reference = const value_type&;

    private:
        size_type m_addr{};
    public:
        explicit MemoryRegionAddress(size_type addr=0) noexcept : m_addr{addr} {}

        auto data() const noexcept -> size_type override;

        // Returns the bitwise AND of the address and a mask.
        auto operator&(const size_type mask) const noexcept -> size_type override;

        // Returns the bitwise OR of the address and a mask.
        auto operator|(const size_type mask) const noexcept -> size_type override;

        // Returns the address plus some value (sum is wrapped).
        auto operator+(const size_type val) const noexcept -> value_type override;

        // Returns the sum of the address and another address (sum is wrapped).
        auto operator+(const_reference addr) const noexcept -> value_type override;

        // Returns the address minus some value (difference is wrapped).
        auto operator-(const size_type val) const noexcept -> value_type override;

        // Returns the difference between the address and another address
        // (difference is wrapped).
        auto operator-(const_reference addr) const noexcept -> value_type override;

        // Aligns the address to a power of 2.
        auto align(const size_type alignment) noexcept -> reference override;
};

}  // vmm::memory::detail

M vmm/memory/memory.hpp => vmm/memory/memory.hpp +1 -0
@@ 16,5 16,6 @@ template<typename T, typename S>
using Address = vmm::memory::detail::Address<T, S>;

using GuestAddress = vmm::memory::detail::GuestAddress;
using MemoryRegionAddress = vmm::memory::detail::MemoryRegionAddress;

}  // vmm::memory