Gabe Black has submitted this change and it was merged. (
https://gem5-review.googlesource.com/7562 )
Change subject: arch: Add a virtual asBytes function to the StaticInst
class.
......................................................................
arch: Add a virtual asBytes function to the StaticInst class.
This function takes a pointer to a buffer and the current size of the
buffer as a pass by reference argument. If the size of the buffer is
sufficient, the function stores a binary representation of itself
(generally the ISA defined instruction encoding) in the buffer, and
sets the size argument to how much space it used. This could be used
by ISAs which have two instruction sizes (ARM and thumb, for example).
If the buffer size isn't sufficient, then the size parameter should be
set to what size is required, and then the function should return
without modifying the buffer.
The buffer itself should be aligned to the same standard as memory
returned by new, specifically "The pointer returned shall be suitably
aligned so that it can be converted to a pointer of any complete object
type and then used to access the object or array in the storage
allocated...". This will avoid having to memcpy buffers to avoid
unaligned accesses.
To standardize the representation of the data, it should be stored in
the buffer as little endian. Since most hosts (including ARM and x86
hosts) will be little endian, this will almost always be a no-op.
Change-Id: I2f31aa0b4f9c0126b44f47a881c2901243279bd6
Reviewed-on: https://gem5-review.googlesource.com/7562
Reviewed-by: Andreas Sandberg <[email protected]>
Maintainer: Gabe Black <[email protected]>
---
M src/arch/alpha/isa/main.isa
M src/arch/arm/insts/static_inst.hh
M src/arch/mips/isa/base.isa
M src/arch/power/insts/static_inst.hh
M src/arch/riscv/insts/static_inst.hh
M src/arch/sparc/insts/static_inst.hh
M src/cpu/static_inst.hh
7 files changed, 67 insertions(+), 2 deletions(-)
Approvals:
Andreas Sandberg: Looks good to me, approved
Gabe Black: Looks good to me, approved
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index a23710a..4f269b3 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -51,6 +51,8 @@
#include "cpu/static_inst.hh"
#include "mem/packet.hh"
#include "mem/request.hh" // some constructors use MemReq flags
+#include "sim/byteswap.hh"
+
}};
output decoder {{
@@ -59,9 +61,9 @@
#include "arch/alpha/decoder.hh"
#include "arch/alpha/registers.hh"
#include "arch/alpha/regredir.hh"
-#include "base/loader/symtab.hh"
#include "base/cprintf.hh"
#include "base/fenv.hh"
+#include "base/loader/symtab.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include "mem/packet.hh"
@@ -219,7 +221,6 @@
class AlphaStaticInst : public StaticInst
{
protected:
-
/// Constructor.
AlphaStaticInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
@@ -239,6 +240,13 @@
{
pcState.advance();
}
+
+ public:
+ size_t
+ asBytes(void *buf, size_t max_size) override
+ {
+ return simpleAsBytes(buf, max_size, machInst);
+ }
};
}};
diff --git a/src/arch/arm/insts/static_inst.hh
b/src/arch/arm/insts/static_inst.hh
index c68880c..3ed374a 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -505,6 +505,12 @@
{
return static_cast<MachInst>(machInst & (mask(instSize() * 8)));
}
+
+ size_t
+ asBytes(void *buf, size_t max_size) override
+ {
+ return simpleAsBytes(buf, max_size, machInst);
+ }
};
}
diff --git a/src/arch/mips/isa/base.isa b/src/arch/mips/isa/base.isa
index 946dce6..3759390 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -63,6 +63,12 @@
{
pc.advance();
}
+
+ size_t
+ asBytes(void *buf, size_t max_size) override
+ {
+ return simpleAsBytes(buf, max_size, machInst);
+ }
};
}};
diff --git a/src/arch/power/insts/static_inst.hh
b/src/arch/power/insts/static_inst.hh
index b7a818a..f4f1bec 100644
--- a/src/arch/power/insts/static_inst.hh
+++ b/src/arch/power/insts/static_inst.hh
@@ -69,6 +69,12 @@
{
pcState.advance();
}
+
+ size_t
+ asBytes(void *buf, size_t max_size) override
+ {
+ return simpleAsBytes(buf, max_size, machInst);
+ }
};
} // namespace PowerISA
diff --git a/src/arch/riscv/insts/static_inst.hh
b/src/arch/riscv/insts/static_inst.hh
index 073b60c..3f6d586 100644
--- a/src/arch/riscv/insts/static_inst.hh
+++ b/src/arch/riscv/insts/static_inst.hh
@@ -56,6 +56,12 @@
public:
void advancePC(PCState &pc) const { pc.advance(); }
+
+ size_t
+ asBytes(void *buf, size_t size) override
+ {
+ return simpleAsBytes(buf, size, machInst);
+ }
};
/**
diff --git a/src/arch/sparc/insts/static_inst.hh
b/src/arch/sparc/insts/static_inst.hh
index cc5a602..9e15c8d 100644
--- a/src/arch/sparc/insts/static_inst.hh
+++ b/src/arch/sparc/insts/static_inst.hh
@@ -105,6 +105,12 @@
static bool passesFpCondition(uint32_t fcc, uint32_t condition);
static bool passesCondition(uint32_t codes, uint32_t condition);
+
+ size_t
+ asBytes(void *buf, size_t size) override
+ {
+ return simpleAsBytes(buf, size, machInst);
+ }
};
}
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 79f45d8..84b3525 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -33,6 +33,7 @@
#define __CPU_STATIC_INST_HH__
#include <bitset>
+#include <memory>
#include <string>
#include "arch/registers.hh"
@@ -47,6 +48,7 @@
#include "cpu/static_inst_fwd.hh"
#include "cpu/thread_context.hh"
#include "enums/StaticInstFlags.hh"
+#include "sim/byteswap.hh"
// forward declarations
class Packet;
@@ -317,6 +319,31 @@
/// Return name of machine instruction
std::string getName() { return mnemonic; }
+
+ protected:
+ template<typename T>
+ size_t
+ simpleAsBytes(void *buf, size_t max_size, const T &t)
+ {
+ size_t size = sizeof(T);
+ if (size <= max_size)
+ *reinterpret_cast<T *>(buf) = htole<T>(t);
+ return size;
+ }
+
+ public:
+ /**
+ * Instruction classes can override this function to return a
+ * a representation of themselves as a blob of bytes, generally
assumed to
+ * be that instructions ExtMachInst.
+ *
+ * buf is a buffer to hold the bytes.
+ * max_size is the size allocated for that buffer by the caller.
+ * The return value is how much data was actually put into the buffer,
+ * zero if no data was put in the buffer, or the necessary size of the
+ * buffer if there wasn't enough space.
+ */
+ virtual size_t asBytes(void *buf, size_t max_size) { return 0; }
};
#endif // __CPU_STATIC_INST_HH__
--
To view, visit https://gem5-review.googlesource.com/7562
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I2f31aa0b4f9c0126b44f47a881c2901243279bd6
Gerrit-Change-Number: 7562
Gerrit-PatchSet: 3
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Brandon Potter <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev