Gabe Black has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/52041 )
Change subject: arch: Add a "set" function to set one PCState to another.
......................................................................
arch: Add a "set" function to set one PCState to another.
Most of the time, the type pointed to by a PCState pointer or reference
will be the same as all the others, if not nullptr.
This change adds a set of "set" functions which assume that the
underlying type of each pointer or reference are the same, and handles
casting, copying things over, creating a new copy, etc, for you. It uses
a new "update" virtual method on PCState subclasses which casts the
source to the same type as the destination and copies values over.
Note that the "set" function doesn't actually verify that the two types
are the same, just like the overloaded ==, != and << operators. In the
future, those checks can be added for debugging purposes, probably
guarded by a configuration variable which can be toggled on or off to
get better performance or more thorough error checking.
The main advantage of these wrappers are that they allows consistent
semantics whether your moving a value from a pointer, or from a yet
unconverted PCState subclass, or vice versa, which will be particularly
helpful while transitioning between using raw PCState instances and
using primarily pointers and references.
This change also adds wrappers which handle std::unique_ptr, which makes
it easier to use them as arguments to these functions. Otherwise, if the
std::unique_ptr is a temporary value, using the return value of .get()
will let the std::unique_ptr go out of scope, making it delete the data
pointed to by the returned pointed. By keeping the std::unique_ptr
around on the stack, that prevents it from going out of scope.
Change-Id: I2c737b08e0590a2c46e212a7b9efa543bdb81ad3
---
M src/arch/x86/pcstate.hh
M src/arch/generic/pcstate.hh
M src/arch/arm/pcstate.hh
M src/arch/power/pcstate.hh
M src/arch/riscv/pcstate.hh
5 files changed, 183 insertions(+), 0 deletions(-)
diff --git a/src/arch/arm/pcstate.hh b/src/arch/arm/pcstate.hh
index b1d0b74..122cd9b 100644
--- a/src/arch/arm/pcstate.hh
+++ b/src/arch/arm/pcstate.hh
@@ -111,6 +111,21 @@
PCStateBase *clone() const override { return new PCState(*this); }
+ void
+ update(const PCStateBase &other) override
+ {
+ Base::update(other);
+ auto &pcstate = other.as<PCState>();
+ flags = pcstate.flags;
+ nextFlags = pcstate.nextFlags;
+ _itstate = pcstate._itstate;
+ _nextItstate = pcstate._nextItstate;
+ _size = pcstate._size;
+ _illegalExec = pcstate._illegalExec;
+ _debugStep = pcstate._debugStep;
+ _stepped = pcstate._stepped;
+ }
+
bool
illegalExec() const
{
diff --git a/src/arch/generic/pcstate.hh b/src/arch/generic/pcstate.hh
index 0acd3c9..dd61377 100644
--- a/src/arch/generic/pcstate.hh
+++ b/src/arch/generic/pcstate.hh
@@ -42,7 +42,9 @@
#define __ARCH_GENERIC_TYPES_HH__
#include <iostream>
+#include <type_traits>
+#include "base/compiler.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "sim/serialize.hh"
@@ -79,6 +81,13 @@
}
virtual PCStateBase *clone() const = 0;
+ virtual void
+ update(const PCStateBase &other)
+ {
+ _pc = other._pc;
+ _upc = other._upc;
+ }
+ void update(const PCStateBase *ptr) { update(*ptr); }
virtual void output(std::ostream &os) const = 0;
@@ -144,6 +153,86 @@
return !a.equals(b);
}
+namespace
+{
+
+inline void
+set(PCStateBase *&dest, const PCStateBase *src)
+{
+ if (GEM5_LIKELY(dest)) {
+ if (GEM5_LIKELY(src)) {
+ // Update dest with the contents of src.
+ dest->update(src);
+ } else {
+ // Clear out dest.
+ dest = nullptr;
+ }
+ } else {
+ if (GEM5_LIKELY(src)) {
+ // Create a copy of src and point dest at it.
+ dest = src->clone();
+ } else {
+ // dest is already nullptr.
+ }
+ }
+}
+
+inline void
+set(std::unique_ptr<PCStateBase> &dest, const PCStateBase *src)
+{
+ PCStateBase *dest_ptr = dest.get();
+ set(dest_ptr, src);
+ if (dest.get() != dest_ptr)
+ dest.reset(dest_ptr);
+}
+
+inline void
+set(PCStateBase *&dest, const std::unique_ptr<PCStateBase> &src)
+{
+ const PCStateBase *src_ptr = src.get();
+ set(dest, src_ptr);
+}
+
+inline void
+set(std::unique_ptr<PCStateBase> &dest,
+ const std::unique_ptr<PCStateBase> &src)
+{
+ PCStateBase *dest_ptr = dest.get();
+ const PCStateBase *src_ptr = src.get();
+ set(dest_ptr, src_ptr);
+ if (dest.get() != dest_ptr)
+ dest.reset(dest_ptr);
+}
+
+inline void
+set(PCStateBase *&dest, const PCStateBase &src)
+{
+ if (GEM5_LIKELY(dest)) {
+ // Update dest with the contents of src.
+ dest->update(src);
+ } else {
+ // Clone src over to dest.
+ dest = src.clone();
+ }
+}
+
+inline void
+set(std::unique_ptr<PCStateBase> &dest, const PCStateBase &src)
+{
+ PCStateBase *dest_ptr = dest.get();
+ set(dest_ptr, src);
+ if (dest.get() != dest_ptr)
+ dest.reset(dest_ptr);
+}
+
+inline void
+set(PCStateBase &dest, const PCStateBase &src)
+{
+ dest.update(src);
+}
+
+} // anonymous namespace
+
namespace GenericISA
{
@@ -201,6 +290,15 @@
*/
void set(Addr val);
+ void
+ update(const PCStateBase &other) override
+ {
+ PCStateBase::update(other);
+ auto &pcstate = other.as<PCStateCommon>();
+ _npc = pcstate._npc;
+ _nupc = pcstate._nupc;
+ }
+
bool
equals(const PCStateBase &other) const override
{
@@ -367,6 +465,14 @@
return new DelaySlotPCState<InstWidth>(*this);
}
+ void
+ update(const PCStateBase &other) override
+ {
+ Base::update(other);
+ auto &pcstate = other.as<DelaySlotPCState<InstWidth>>();
+ _nnpc = pcstate._nnpc;
+ }
+
Addr nnpc() const { return _nnpc; }
void nnpc(Addr val) { _nnpc = val; }
diff --git a/src/arch/power/pcstate.hh b/src/arch/power/pcstate.hh
index 2b5ddd3..0e21aee 100644
--- a/src/arch/power/pcstate.hh
+++ b/src/arch/power/pcstate.hh
@@ -55,6 +55,14 @@
PCStateBase *clone() const override { return new PCState(*this); }
+ void
+ update(const PCStateBase &other) override
+ {
+ GenericISA::SimplePCState<4>::update(other);
+ auto &pcstate = other.as<PCState>();
+ guestByteOrder = pcstate.guestByteOrder;
+ }
+
ByteOrder
byteOrder() const
{
diff --git a/src/arch/riscv/pcstate.hh b/src/arch/riscv/pcstate.hh
index 3187318..53b358c 100644
--- a/src/arch/riscv/pcstate.hh
+++ b/src/arch/riscv/pcstate.hh
@@ -61,6 +61,15 @@
PCStateBase *clone() const override { return new PCState(*this); }
+ void
+ update(const PCStateBase &other) override
+ {
+ Base::update(other);
+ auto &pcstate = other.as<PCState>();
+ _compressed = pcstate._compressed;
+ _rv32 = pcstate._rv32;
+ }
+
void compressed(bool c) { _compressed = c; }
bool compressed() const { return _compressed; }
diff --git a/src/arch/x86/pcstate.hh b/src/arch/x86/pcstate.hh
index c0641ca..8d74806 100644
--- a/src/arch/x86/pcstate.hh
+++ b/src/arch/x86/pcstate.hh
@@ -58,6 +58,14 @@
PCStateBase *clone() const override { return new PCState(*this); }
void
+ update(const PCStateBase &other) override
+ {
+ Base::update(other);
+ auto &pcstate = other.as<PCState>();
+ _size = pcstate._size;
+ }
+
+ void
set(Addr val)
{
Base::set(val);
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/52041
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I2c737b08e0590a2c46e212a7b9efa543bdb81ad3
Gerrit-Change-Number: 52041
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s