summaryrefslogtreecommitdiff
path: root/src/core/memory.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.h')
-rw-r--r--src/core/memory.h125
1 files changed, 65 insertions, 60 deletions
diff --git a/src/core/memory.h b/src/core/memory.h
index 2eb61ffd3..13047a545 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -509,9 +509,9 @@ class GuestMemory {
509 509
510public: 510public:
511 GuestMemory() = delete; 511 GuestMemory() = delete;
512 explicit GuestMemory(M& memory_, u64 addr_, std::size_t size_, 512 explicit GuestMemory(M& memory, u64 addr, std::size_t size,
513 Common::ScratchBuffer<T>* backup = nullptr) 513 Common::ScratchBuffer<T>* backup = nullptr)
514 : memory{memory_}, addr{addr_}, size{size_} { 514 : m_memory{memory}, m_addr{addr}, m_size{size} {
515 static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write); 515 static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write);
516 if constexpr (FLAGS & GuestMemoryFlags::Read) { 516 if constexpr (FLAGS & GuestMemoryFlags::Read) {
517 Read(addr, size, backup); 517 Read(addr, size, backup);
@@ -521,89 +521,97 @@ public:
521 ~GuestMemory() = default; 521 ~GuestMemory() = default;
522 522
523 T* data() noexcept { 523 T* data() noexcept {
524 return data_span.data(); 524 return m_data_span.data();
525 } 525 }
526 526
527 const T* data() const noexcept { 527 const T* data() const noexcept {
528 return data_span.data(); 528 return m_data_span.data();
529 }
530
531 size_t size() const noexcept {
532 return m_size;
533 }
534
535 size_t size_bytes() const noexcept {
536 return this->size() * sizeof(T);
529 } 537 }
530 538
531 [[nodiscard]] T* begin() noexcept { 539 [[nodiscard]] T* begin() noexcept {
532 return data(); 540 return this->data();
533 } 541 }
534 542
535 [[nodiscard]] const T* begin() const noexcept { 543 [[nodiscard]] const T* begin() const noexcept {
536 return data(); 544 return this->data();
537 } 545 }
538 546
539 [[nodiscard]] T* end() noexcept { 547 [[nodiscard]] T* end() noexcept {
540 return data() + size; 548 return this->data() + this->size();
541 } 549 }
542 550
543 [[nodiscard]] const T* end() const noexcept { 551 [[nodiscard]] const T* end() const noexcept {
544 return data() + size; 552 return this->data() + this->size();
545 } 553 }
546 554
547 T& operator[](size_t index) noexcept { 555 T& operator[](size_t index) noexcept {
548 return data_span[index]; 556 return m_data_span[index];
549 } 557 }
550 558
551 const T& operator[](size_t index) const noexcept { 559 const T& operator[](size_t index) const noexcept {
552 return data_span[index]; 560 return m_data_span[index];
553 } 561 }
554 562
555 void SetAddressAndSize(u64 addr_, std::size_t size_) noexcept { 563 void SetAddressAndSize(u64 addr, std::size_t size) noexcept {
556 addr = addr_; 564 m_addr = addr;
557 size = size_; 565 m_size = size;
558 addr_changed = true; 566 m_addr_changed = true;
559 } 567 }
560 568
561 std::span<T> Read(u64 addr_, std::size_t size_, 569 std::span<T> Read(u64 addr, std::size_t size,
562 Common::ScratchBuffer<T>* backup = nullptr) noexcept { 570 Common::ScratchBuffer<T>* backup = nullptr) noexcept {
563 addr = addr_; 571 m_addr = addr;
564 size = size_; 572 m_size = size;
565 if (size == 0) { 573 if (m_size == 0) {
566 is_data_copy = true; 574 m_is_data_copy = true;
567 return {}; 575 return {};
568 } 576 }
569 577
570 if (TrySetSpan()) { 578 if (this->TrySetSpan()) {
571 if constexpr (FLAGS & GuestMemoryFlags::Safe) { 579 if constexpr (FLAGS & GuestMemoryFlags::Safe) {
572 memory.FlushRegion(addr, size * sizeof(T)); 580 m_memory.FlushRegion(m_addr, this->size_bytes());
573 } 581 }
574 } else { 582 } else {
575 if (backup) { 583 if (backup) {
576 backup->resize_destructive(size); 584 backup->resize_destructive(this->size());
577 data_span = *backup; 585 m_data_span = *backup;
578 } else { 586 } else {
579 data_copy.resize(size); 587 m_data_copy.resize(this->size());
580 data_span = std::span(data_copy); 588 m_data_span = std::span(m_data_copy);
581 } 589 }
582 is_data_copy = true; 590 m_is_data_copy = true;
583 span_valid = true; 591 m_span_valid = true;
584 if constexpr (FLAGS & GuestMemoryFlags::Safe) { 592 if constexpr (FLAGS & GuestMemoryFlags::Safe) {
585 memory.ReadBlock(addr, data_span.data(), size * sizeof(T)); 593 m_memory.ReadBlock(m_addr, this->data(), this->size_bytes());
586 } else { 594 } else {
587 memory.ReadBlockUnsafe(addr, data_span.data(), size * sizeof(T)); 595 m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes());
588 } 596 }
589 } 597 }
590 return data_span; 598 return m_data_span;
591 } 599 }
592 600
593 void Write(std::span<T> write_data) noexcept { 601 void Write(std::span<T> write_data) noexcept {
594 if constexpr (FLAGS & GuestMemoryFlags::Cached) { 602 if constexpr (FLAGS & GuestMemoryFlags::Cached) {
595 memory.WriteBlockCached(addr, write_data.data(), size * sizeof(T)); 603 m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes());
596 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 604 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
597 memory.WriteBlock(addr, write_data.data(), size * sizeof(T)); 605 m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes());
598 } else { 606 } else {
599 memory.WriteBlockUnsafe(addr, write_data.data(), size * sizeof(T)); 607 m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes());
600 } 608 }
601 } 609 }
602 610
603 bool TrySetSpan() noexcept { 611 bool TrySetSpan() noexcept {
604 if (u8* ptr = memory.GetSpan(addr, size * sizeof(T)); ptr) { 612 if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) {
605 data_span = {reinterpret_cast<T*>(ptr), size}; 613 m_data_span = {reinterpret_cast<T*>(ptr), this->size()};
606 span_valid = true; 614 m_span_valid = true;
607 return true; 615 return true;
608 } 616 }
609 return false; 617 return false;
@@ -611,36 +619,36 @@ public:
611 619
612protected: 620protected:
613 bool IsDataCopy() const noexcept { 621 bool IsDataCopy() const noexcept {
614 return is_data_copy; 622 return m_is_data_copy;
615 } 623 }
616 624
617 bool AddressChanged() const noexcept { 625 bool AddressChanged() const noexcept {
618 return addr_changed; 626 return m_addr_changed;
619 } 627 }
620 628
621 M& memory; 629 M& m_memory;
622 u64 addr; 630 u64 m_addr{};
623 size_t size; 631 size_t m_size{};
624 std::span<T> data_span{}; 632 std::span<T> m_data_span{};
625 std::vector<T> data_copy; 633 std::vector<T> m_data_copy{};
626 bool span_valid{false}; 634 bool m_span_valid{false};
627 bool is_data_copy{false}; 635 bool m_is_data_copy{false};
628 bool addr_changed{false}; 636 bool m_addr_changed{false};
629}; 637};
630 638
631template <typename M, typename T, GuestMemoryFlags FLAGS> 639template <typename M, typename T, GuestMemoryFlags FLAGS>
632class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> { 640class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> {
633public: 641public:
634 GuestMemoryScoped() = delete; 642 GuestMemoryScoped() = delete;
635 explicit GuestMemoryScoped(M& memory_, u64 addr_, std::size_t size_, 643 explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size,
636 Common::ScratchBuffer<T>* backup = nullptr) 644 Common::ScratchBuffer<T>* backup = nullptr)
637 : GuestMemory<M, T, FLAGS>(memory_, addr_, size_, backup) { 645 : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) {
638 if constexpr (!(FLAGS & GuestMemoryFlags::Read)) { 646 if constexpr (!(FLAGS & GuestMemoryFlags::Read)) {
639 if (!this->TrySetSpan()) { 647 if (!this->TrySetSpan()) {
640 if (backup) { 648 if (backup) {
641 this->data_span = *backup; 649 this->m_data_span = *backup;
642 this->span_valid = true; 650 this->m_span_valid = true;
643 this->is_data_copy = true; 651 this->m_is_data_copy = true;
644 } 652 }
645 } 653 }
646 } 654 }
@@ -648,24 +656,21 @@ public:
648 656
649 ~GuestMemoryScoped() { 657 ~GuestMemoryScoped() {
650 if constexpr (FLAGS & GuestMemoryFlags::Write) { 658 if constexpr (FLAGS & GuestMemoryFlags::Write) {
651 if (this->size == 0) [[unlikely]] { 659 if (this->size() == 0) [[unlikely]] {
652 return; 660 return;
653 } 661 }
654 662
655 if (this->AddressChanged() || this->IsDataCopy()) { 663 if (this->AddressChanged() || this->IsDataCopy()) {
656 ASSERT(this->span_valid); 664 ASSERT(this->m_span_valid);
657 if constexpr (FLAGS & GuestMemoryFlags::Cached) { 665 if constexpr (FLAGS & GuestMemoryFlags::Cached) {
658 this->memory.WriteBlockCached(this->addr, this->data_span.data(), 666 this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes());
659 this->size * sizeof(T));
660 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 667 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
661 this->memory.WriteBlock(this->addr, this->data_span.data(), 668 this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes());
662 this->size * sizeof(T));
663 } else { 669 } else {
664 this->memory.WriteBlockUnsafe(this->addr, this->data_span.data(), 670 this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes());
665 this->size * sizeof(T));
666 } 671 }
667 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { 672 } else if constexpr (FLAGS & GuestMemoryFlags::Safe) {
668 this->memory.InvalidateRegion(this->addr, this->size * sizeof(T)); 673 this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes());
669 } 674 }
670 } 675 }
671 } 676 }