summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2018-01-23 23:57:48 -0800
committerGabe Black <gabeblack@google.com>2018-03-26 22:33:52 +0000
commit81050be736f0d7ac71e7f862a4f34b1ed6787716 (patch)
tree7270526d3375cf0464c07a6c4e2feefbb16faba1
parentf6a28e5fc2e698cb7c6f35bb2476a1cce9f689d2 (diff)
downloadgem5-81050be736f0d7ac71e7f862a4f34b1ed6787716.tar.xz
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 <andreas.sandberg@arm.com> Maintainer: Gabe Black <gabeblack@google.com>
-rw-r--r--src/arch/alpha/isa/main.isa12
-rw-r--r--src/arch/arm/insts/static_inst.hh6
-rw-r--r--src/arch/mips/isa/base.isa6
-rw-r--r--src/arch/power/insts/static_inst.hh6
-rw-r--r--src/arch/riscv/insts/static_inst.hh6
-rw-r--r--src/arch/sparc/insts/static_inst.hh6
-rw-r--r--src/cpu/static_inst.hh27
7 files changed, 67 insertions, 2 deletions
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index a23710a2d..4f269b373 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -51,6 +51,8 @@ output header {{
#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 @@ output decoder {{
#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 @@ output header {{
class AlphaStaticInst : public StaticInst
{
protected:
-
/// Constructor.
AlphaStaticInst(const char *mnem, ExtMachInst _machInst,
OpClass __opClass)
@@ -239,6 +240,13 @@ output header {{
{
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 c68880c97..3ed374ab1 100644
--- a/src/arch/arm/insts/static_inst.hh
+++ b/src/arch/arm/insts/static_inst.hh
@@ -505,6 +505,12 @@ class ArmStaticInst : public StaticInst
{
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 946dce6df..3759390d1 100644
--- a/src/arch/mips/isa/base.isa
+++ b/src/arch/mips/isa/base.isa
@@ -63,6 +63,12 @@ output header {{
{
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 b7a818a2c..f4f1bec7b 100644
--- a/src/arch/power/insts/static_inst.hh
+++ b/src/arch/power/insts/static_inst.hh
@@ -69,6 +69,12 @@ class PowerStaticInst : public StaticInst
{
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 073b60c1c..3f6d58654 100644
--- a/src/arch/riscv/insts/static_inst.hh
+++ b/src/arch/riscv/insts/static_inst.hh
@@ -56,6 +56,12 @@ class RiscvStaticInst : public StaticInst
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 cc5a60225..9e15c8dab 100644
--- a/src/arch/sparc/insts/static_inst.hh
+++ b/src/arch/sparc/insts/static_inst.hh
@@ -105,6 +105,12 @@ class SparcStaticInst : public StaticInst
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 79f45d828..84b352502 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 @@ class StaticInst : public RefCounted, public StaticInstFlags
/// 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__