arch,cpu,sim: Store registers in InstRecord with InstResult.

The InstResult knows how to print registers without having to know about
their actual types.

Change-Id: Ib858e32a7b2fabbde4857165b9e88e87294942c8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50254
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
This commit is contained in:
Gabe Black
2021-09-11 04:19:55 -07:00
parent 81e07670b9
commit e425bcabd2
8 changed files with 55 additions and 65 deletions

View File

@@ -46,7 +46,7 @@
#include "arch/generic/pcstate.hh"
#include "arch/vecregs.hh"
#include "base/types.hh"
#include "config/the_isa.hh"
#include "cpu/inst_res.hh"
#include "cpu/inst_seq.hh"
#include "cpu/static_inst.hh"
#include "sim/sim_object.hh"
@@ -97,13 +97,14 @@ class InstRecord
* @TODO fix this and record all destintations that an instruction writes
* @see data_status
*/
union
union Data
{
uint64_t as_int;
double as_double;
TheISA::VecRegContainer* as_vec;
TheISA::VecPredRegContainer* as_pred;
} data = {0};
~Data() {}
Data() {}
uint64_t asInt = 0;
double asDouble;
InstResult asReg;
} data;
/** @defgroup fetch_seq
* This records the serial number that the instruction was fetched in.
@@ -128,9 +129,8 @@ class InstRecord
DataInt32 = 4,
DataInt64 = 8,
DataDouble = 3,
DataVec = 5,
DataVecPred = 6
} data_status = DataInvalid;
DataReg = 5
} dataStatus = DataInvalid;
/** @ingroup memory
* Are the memory fields in the record valid?
@@ -166,13 +166,8 @@ class InstRecord
virtual ~InstRecord()
{
if (data_status == DataVec) {
assert(data.as_vec);
delete data.as_vec;
} else if (data_status == DataVecPred) {
assert(data.as_pred);
delete data.as_pred;
}
if (dataStatus == DataReg)
data.asReg.~InstResult();
}
void setWhen(Tick new_when) { when = new_when; }
@@ -189,8 +184,8 @@ class InstRecord
void
setData(std::array<T, N> d)
{
data.as_int = d[0];
data_status = (DataStatus)sizeof(T);
data.asInt = d[0];
dataStatus = (DataStatus)sizeof(T);
static_assert(sizeof(T) == DataInt8 || sizeof(T) == DataInt16 ||
sizeof(T) == DataInt32 || sizeof(T) == DataInt64,
"Type T has an unrecognized size.");
@@ -199,26 +194,26 @@ class InstRecord
void
setData(uint64_t d)
{
data.as_int = d;
data_status = DataInt64;
data.asInt = d;
dataStatus = DataInt64;
}
void
setData(uint32_t d)
{
data.as_int = d;
data_status = DataInt32;
data.asInt = d;
dataStatus = DataInt32;
}
void
setData(uint16_t d)
{
data.as_int = d;
data_status = DataInt16;
data.asInt = d;
dataStatus = DataInt16;
}
void
setData(uint8_t d)
{
data.as_int = d;
data_status = DataInt8;
data.asInt = d;
dataStatus = DataInt8;
}
void setData(int64_t d) { setData((uint64_t)d); }
@@ -229,22 +224,22 @@ class InstRecord
void
setData(double d)
{
data.as_double = d;
data_status = DataDouble;
data.asDouble = d;
dataStatus = DataDouble;
}
void
setData(TheISA::VecRegContainer& d)
setData(const RegClass &reg_class, RegVal val)
{
data.as_vec = new TheISA::VecRegContainer(d);
data_status = DataVec;
new(&data.asReg) InstResult(reg_class, val);
dataStatus = DataReg;
}
void
setData(TheISA::VecPredRegContainer& d)
setData(const RegClass &reg_class, const void *val)
{
data.as_pred = new TheISA::VecPredRegContainer(d);
data_status = DataVecPred;
new(&data.asReg) InstResult(reg_class, val);
dataStatus = DataReg;
}
void
@@ -279,9 +274,9 @@ class InstRecord
unsigned getFlags() const { return flags; }
bool getMemValid() const { return mem_valid; }
uint64_t getIntData() const { return data.as_int; }
double getFloatData() const { return data.as_double; }
int getDataStatus() const { return data_status; }
uint64_t getIntData() const { return data.asInt; }
double getFloatData() const { return data.asDouble; }
int getDataStatus() const { return dataStatus; }
InstSeqNum getFetchSeq() const { return fetch_seq; }
bool getFetchSeqValid() const { return fetch_seq_valid; }