summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGiacomo Gabrielli <giacomo.gabrielli@arm.com>2019-09-30 14:30:48 +0100
committerGiacomo Travaglini <giacomo.travaglini@arm.com>2019-11-11 10:12:54 +0000
commit68a4a2de66430e4d435726182f930acbd9a91b8b (patch)
tree86c2bc958626ef680f4a49f2b61455a716baf360 /src/arch
parent27c262735cb6d33b01e21e1f3ba73a32965024b9 (diff)
downloadgem5-68a4a2de66430e4d435726182f930acbd9a91b8b.tar.xz
arch-arm: Provide SVE support to the TarmacParser
This patch is providing SVE support to the tarmac parser, so that it is recognizing Vector & Predicate entries. Change-Id: I268e621cffa05644d3f1d80170b067aacaa2d5ea Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Giacomo Gabrielli <giacomo.gabrielli@arm.com> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21560 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/arm/tracers/tarmac_base.cc7
-rw-r--r--src/arch/arm/tracers/tarmac_base.hh14
-rw-r--r--src/arch/arm/tracers/tarmac_parser.cc243
-rw-r--r--src/arch/arm/tracers/tarmac_parser.hh5
-rw-r--r--src/arch/arm/tracers/tarmac_record.cc14
-rw-r--r--src/arch/arm/tracers/tarmac_record_v8.cc4
6 files changed, 213 insertions, 74 deletions
diff --git a/src/arch/arm/tracers/tarmac_base.cc b/src/arch/arm/tracers/tarmac_base.cc
index 3b6201def..c32784886 100644
--- a/src/arch/arm/tracers/tarmac_base.cc
+++ b/src/arch/arm/tracers/tarmac_base.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -83,8 +83,11 @@ TarmacBaseRecord::InstEntry::InstEntry(
}
TarmacBaseRecord::RegEntry::RegEntry(PCState pc)
- : isetstate(pcToISetState(pc))
+ : isetstate(pcToISetState(pc)),
+ values(2, 0)
{
+ // values vector is constructed with size = 2, for
+ // holding Lo and Hi values.
}
TarmacBaseRecord::MemEntry::MemEntry (
diff --git a/src/arch/arm/tracers/tarmac_base.hh b/src/arch/arm/tracers/tarmac_base.hh
index 4e6cbe0f3..4cd18487f 100644
--- a/src/arch/arm/tracers/tarmac_base.hh
+++ b/src/arch/arm/tracers/tarmac_base.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011,2017-2018 ARM Limited
+ * Copyright (c) 2011,2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -78,7 +78,7 @@ class TarmacBaseRecord : public InstRecord
ISET_UNSUPPORTED };
/** ARM register type. */
- enum RegType { REG_R, REG_X, REG_S, REG_D, REG_Q, REG_MISC };
+ enum RegType { REG_R, REG_X, REG_S, REG_D, REG_P, REG_Q, REG_Z, REG_MISC };
/** TARMAC instruction trace record. */
struct InstEntry
@@ -100,14 +100,20 @@ class TarmacBaseRecord : public InstRecord
/** TARMAC register trace record. */
struct RegEntry
{
+ enum RegElement {
+ Lo = 0,
+ Hi = 1,
+ // Max = (max SVE vector length) 2048b / 64 = 32
+ Max = 32
+ };
+
RegEntry() = default;
RegEntry(ArmISA::PCState pc);
RegType type;
RegIndex index;
ISetState isetstate;
- uint64_t valueHi;
- uint64_t valueLo;
+ std::vector<uint64_t> values;
};
/** TARMAC memory access trace record (stores only). */
diff --git a/src/arch/arm/tracers/tarmac_parser.cc b/src/arch/arm/tracers/tarmac_parser.cc
index 04a2a051e..9089e3f6d 100644
--- a/src/arch/arm/tracers/tarmac_parser.cc
+++ b/src/arch/arm/tracers/tarmac_parser.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011,2017-2018 ARM Limited
+ * Copyright (c) 2011,2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -63,6 +63,7 @@ namespace Trace {
// TARMAC Parser static variables
const int TarmacParserRecord::MaxLineLength;
+int8_t TarmacParserRecord::maxVectorLength = 0;
TarmacParserRecord::ParserInstEntry TarmacParserRecord::instRecord;
TarmacParserRecord::ParserRegEntry TarmacParserRecord::regRecord;
@@ -636,47 +637,98 @@ TarmacParserRecord::TarmacParserRecordEvent::process()
list<ParserRegEntry>::iterator it = destRegRecords.begin(),
end = destRegRecords.end();
- uint64_t value_hi, value_lo;
- bool check_value_hi = false;
+ std::vector<uint64_t> values;
for (; it != end; ++it) {
+ values.clear();
switch (it->type) {
case REG_R:
case REG_X:
- value_lo = thread->readIntReg(it->index);
+ values.push_back(thread->readIntReg(it->index));
break;
case REG_S:
- if (instRecord.isetstate == ISET_A64)
- value_lo = thread->readFloatReg(it->index * 4);
- else
- value_lo = thread->readFloatReg(it->index);
+ if (instRecord.isetstate == ISET_A64) {
+ const ArmISA::VecRegContainer& vc = thread->readVecReg(
+ RegId(VecRegClass, it->index));
+ auto vv = vc.as<uint32_t>();
+ values.push_back(vv[0]);
+ } else {
+ const VecElem elem = thread->readVecElem(
+ RegId(VecElemClass,
+ it->index / NumVecElemPerNeonVecReg,
+ it->index % NumVecElemPerNeonVecReg));
+ values.push_back(elem);
+ }
break;
case REG_D:
- if (instRecord.isetstate == ISET_A64)
- value_lo = thread->readFloatReg(it->index * 4) |
- (uint64_t) thread->readFloatReg(it->index * 4 + 1) <<
- 32;
- else
- value_lo = thread->readFloatReg(it->index * 2) |
- (uint64_t) thread->readFloatReg(it->index * 2 + 1) <<
- 32;
+ if (instRecord.isetstate == ISET_A64) {
+ const ArmISA::VecRegContainer& vc = thread->readVecReg(
+ RegId(VecRegClass, it->index));
+ auto vv = vc.as<uint64_t>();
+ values.push_back(vv[0]);
+ } else {
+ const VecElem w0 = thread->readVecElem(
+ RegId(VecElemClass,
+ it->index / NumVecElemPerNeonVecReg,
+ it->index % NumVecElemPerNeonVecReg));
+ const VecElem w1 = thread->readVecElem(
+ RegId(VecElemClass,
+ (it->index + 1) / NumVecElemPerNeonVecReg,
+ (it->index + 1) % NumVecElemPerNeonVecReg));
+
+ values.push_back((uint64_t)(w1) << 32 | w0);
+ }
+ break;
+ case REG_P:
+ {
+ const ArmISA::VecPredRegContainer& pc =
+ thread->readVecPredReg(RegId(VecPredRegClass, it->index));
+ auto pv = pc.as<uint8_t>();
+ uint64_t p = 0;
+ for (int i = maxVectorLength * 8; i > 0; ) {
+ p = (p << 1) | pv[--i];
+ }
+ values.push_back(p);
+ }
break;
case REG_Q:
- check_value_hi = true;
if (instRecord.isetstate == ISET_A64) {
- value_lo = thread->readFloatReg(it->index * 4) |
- (uint64_t) thread->readFloatReg(it->index * 4 + 1) <<
- 32;
- value_hi = thread->readFloatReg(it->index * 4 + 2) |
- (uint64_t) thread->readFloatReg(it->index * 4 + 3) <<
- 32;
+ const ArmISA::VecRegContainer& vc = thread->readVecReg(
+ RegId(VecRegClass, it->index));
+ auto vv = vc.as<uint64_t>();
+ values.push_back(vv[0]);
+ values.push_back(vv[1]);
} else {
- value_lo = thread->readFloatReg(it->index * 2) |
- (uint64_t) thread->readFloatReg(it->index * 2 + 1) <<
- 32;
- value_hi = thread->readFloatReg(it->index * 2 + 2) |
- (uint64_t) thread->readFloatReg(it->index * 2 + 3) <<
- 32;
+ const VecElem w0 = thread->readVecElem(
+ RegId(VecElemClass,
+ it->index / NumVecElemPerNeonVecReg,
+ it->index % NumVecElemPerNeonVecReg));
+ const VecElem w1 = thread->readVecElem(
+ RegId(VecElemClass,
+ (it->index + 1) / NumVecElemPerNeonVecReg,
+ (it->index + 1) % NumVecElemPerNeonVecReg));
+ const VecElem w2 = thread->readVecElem(
+ RegId(VecElemClass,
+ (it->index + 2) / NumVecElemPerNeonVecReg,
+ (it->index + 2) % NumVecElemPerNeonVecReg));
+ const VecElem w3 = thread->readVecElem(
+ RegId(VecElemClass,
+ (it->index + 3) / NumVecElemPerNeonVecReg,
+ (it->index + 3) % NumVecElemPerNeonVecReg));
+
+ values.push_back((uint64_t)(w1) << 32 | w0);
+ values.push_back((uint64_t)(w3) << 32 | w2);
+ }
+ break;
+ case REG_Z:
+ {
+ int8_t i = maxVectorLength;
+ const TheISA::VecRegContainer& vc = thread->readVecReg(
+ RegId(VecRegClass, it->index));
+ auto vv = vc.as<uint64_t>();
+ while (i > 0) {
+ values.push_back(vv[--i]);
+ }
}
break;
case REG_MISC:
@@ -687,41 +739,86 @@ TarmacParserRecord::TarmacParserRecordEvent::process()
cpsr.c = thread->readCCReg(CCREG_C);
cpsr.v = thread->readCCReg(CCREG_V);
cpsr.ge = thread->readCCReg(CCREG_GE);
- value_lo = cpsr;
+ values.push_back(cpsr);
} else if (it->index == MISCREG_NZCV) {
CPSR cpsr = 0;
cpsr.nz = thread->readCCReg(CCREG_NZ);
cpsr.c = thread->readCCReg(CCREG_C);
cpsr.v = thread->readCCReg(CCREG_V);
- value_lo = cpsr;
+ values.push_back(cpsr);
+ } else if (it->index == MISCREG_FPCR) {
+ // Read FPSCR and extract FPCR value
+ FPSCR fpscr = thread->readMiscRegNoEffect(MISCREG_FPSCR);
+ const uint32_t ones = (uint32_t)(-1);
+ FPSCR fpcrMask = 0;
+ fpcrMask.ioe = ones;
+ fpcrMask.dze = ones;
+ fpcrMask.ofe = ones;
+ fpcrMask.ufe = ones;
+ fpcrMask.ixe = ones;
+ fpcrMask.ide = ones;
+ fpcrMask.len = ones;
+ fpcrMask.stride = ones;
+ fpcrMask.rMode = ones;
+ fpcrMask.fz = ones;
+ fpcrMask.dn = ones;
+ fpcrMask.ahp = ones;
+ values.push_back(fpscr & fpcrMask);
+ } else if (it->index == MISCREG_FPSR) {
+ // Read FPSCR and extract FPSR value
+ FPSCR fpscr = thread->readMiscRegNoEffect(MISCREG_FPSCR);
+ const uint32_t ones = (uint32_t)(-1);
+ FPSCR fpsrMask = 0;
+ fpsrMask.ioc = ones;
+ fpsrMask.dzc = ones;
+ fpsrMask.ofc = ones;
+ fpsrMask.ufc = ones;
+ fpsrMask.ixc = ones;
+ fpsrMask.idc = ones;
+ fpsrMask.qc = ones;
+ fpsrMask.v = ones;
+ fpsrMask.c = ones;
+ fpsrMask.z = ones;
+ fpsrMask.n = ones;
+ values.push_back(fpscr & fpsrMask);
} else {
- value_lo = thread->readMiscRegNoEffect(it->index);
+ values.push_back(thread->readMiscRegNoEffect(it->index));
}
break;
default:
panic("Unknown TARMAC trace record type!");
}
- if (value_lo != it->valueLo ||
- (check_value_hi && (value_hi != it->valueHi))) {
- if (!mismatch)
- TarmacParserRecord::printMismatchHeader(inst, pc);
- outs << "diff> [" << it->repr << "] gem5: 0x";
- if (check_value_hi)
- outs << hex << setfill('0') << setw(16) << value_hi
- << setfill('0') << setw(16) << value_lo;
- else
- outs << hex << value_lo;
- outs << ", TARMAC: 0x";
- if (check_value_hi)
- outs << hex << setfill('0') << setw(16) << it->valueHi
- << setfill('0') << setw(16) << it->valueLo << endl;
- else
- outs << it->valueLo << endl;
- mismatch = true;
+ bool same = true;
+ if (values.size() != it->values.size()) same = false;
+
+ uint32_t size = values.size();
+ if (size > it->values.size())
+ size = it->values.size();
+
+ if (same) {
+ for (int i = 0; i < size; ++i) {
+ if (values[i] != it->values[i]) {
+ same = false;
+ break;
+ }
+ }
}
- check_value_hi = false;
+ if (!same) {
+ if (!mismatch) {
+ TarmacParserRecord::printMismatchHeader(inst, pc);
+ mismatch = true;
+ }
+ outs << "diff> [" << it->repr << "] gem5: 0x" << hex;
+ for (auto v : values)
+ outs << setw(16) << setfill('0') << v;
+
+ outs << ", TARMAC: 0x" << hex;
+ for (auto v : it->values)
+ outs << setw(16) << setfill('0') << v;
+ outs << endl;
+ }
}
destRegRecords.clear();
@@ -766,6 +863,9 @@ TarmacParserRecord::TarmacParserRecord(Tick _when, ThreadContext *_thread,
mismatchOnPcOrOpcode(false), parent(_parent)
{
memReq = std::make_shared<Request>();
+ if (maxVectorLength == 0) {
+ maxVectorLength = ArmStaticInst::getCurSveVecLen<uint64_t>(_thread);
+ }
}
void
@@ -936,6 +1036,7 @@ TarmacParserRecord::advanceTrace()
} else if (buf[0] == 'R') {
// Register trace record
currRecordType = TARMAC_REG;
+ regRecord.values.clear();
trace >> buf;
strcpy(regRecord.repr, buf);
if (buf[0] == 'r' && isdigit(buf[1])) {
@@ -981,6 +1082,14 @@ TarmacParserRecord::advanceTrace()
// Q register
regRecord.type = REG_Q;
regRecord.index = atoi(&buf[1]);
+ } else if (buf[0] == 'z' && isdigit(buf[1])) {
+ // Z (SVE vector) register
+ regRecord.type = REG_Z;
+ regRecord.index = atoi(&buf[1]);
+ } else if (buf[0] == 'p' && isdigit(buf[1])) {
+ // P (SVE predicate) register
+ regRecord.type = REG_P;
+ regRecord.index = atoi(&buf[1]);
} else if (strncmp(buf, "SP_EL", 5) == 0) {
// A64 stack pointer
regRecord.type = REG_X;
@@ -1008,20 +1117,38 @@ TarmacParserRecord::advanceTrace()
if (regRecord.type == REG_Q) {
trace.ignore();
trace.get(buf, 17);
- // buf[16] = '\0';
- regRecord.valueHi = strtoull(buf, NULL, 16);
+ uint64_t hi = strtoull(buf, NULL, 16);
trace.get(buf, 17);
- // buf[16] = '\0';
- regRecord.valueLo = strtoull(buf, NULL, 16);
+ uint64_t lo = strtoull(buf, NULL, 16);
+ regRecord.values.push_back(lo);
+ regRecord.values.push_back(hi);
+ } else if (regRecord.type == REG_Z) {
+ regRecord.values.resize(maxVectorLength);
+ for (uint8_t i = 0; i < maxVectorLength; ++i) {
+ uint64_t v;
+ trace >> v;
+ char c;
+ trace >> c;
+ assert(c == '_');
+
+ uint64_t lsw = 0;
+ trace >> lsw;
+ v = (v << 32) | lsw;
+ if (i < maxVectorLength - 1) trace >> c;
+ regRecord.values[i] = v;
+ }
} else {
- trace >> regRecord.valueLo;
+ // REG_P values are also parsed here
+ uint64_t v;
+ trace >> v;
char c = trace.peek();
- if (c == ':') {
- // 64-bit value with colon in the middle
+ if ((c == ':') || (c == '_')) {
+ // 64-bit value with : or _ in the middle
uint64_t lsw = 0;
trace >> c >> lsw;
- regRecord.valueLo = (regRecord.valueLo << 32) | lsw;
+ v = (v << 32) | lsw;
}
+ regRecord.values.push_back(v);
}
trace.ignore(MaxLineLength, '\n');
buf[0] = 0;
diff --git a/src/arch/arm/tracers/tarmac_parser.hh b/src/arch/arm/tracers/tarmac_parser.hh
index afba50fef..ab0c49b9b 100644
--- a/src/arch/arm/tracers/tarmac_parser.hh
+++ b/src/arch/arm/tracers/tarmac_parser.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011,2017-2018 ARM Limited
+ * Copyright (c) 2011,2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -199,6 +199,9 @@ class TarmacParserRecord : public TarmacBaseRecord
/** Request for memory write checks. */
RequestPtr memReq;
+ /** Max. vector length (SVE). */
+ static int8_t maxVectorLength;
+
protected:
TarmacParser& parent;
};
diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc
index 51fbf2c0a..d3df6895c 100644
--- a/src/arch/arm/tracers/tarmac_record.cc
+++ b/src/arch/arm/tracers/tarmac_record.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -195,7 +195,7 @@ TarmacTracerRecord::TraceRegEntry::updateMisc(
regValid = true;
regName = miscRegName[regRelIdx];
- valueLo = thread->readMiscRegNoEffect(regRelIdx);
+ values[Lo] = thread->readMiscRegNoEffect(regRelIdx);
// If it is the CPSR:
// update the value of the CPSR register and add
@@ -208,7 +208,7 @@ TarmacTracerRecord::TraceRegEntry::updateMisc(
cpsr.ge = thread->readCCReg(CCREG_GE);
// update the entry value
- valueLo = cpsr;
+ values[Lo] = cpsr;
}
}
@@ -222,7 +222,7 @@ TarmacTracerRecord::TraceRegEntry::updateCC(
regValid = true;
regName = ccRegName[regRelIdx];
- valueLo = thread->readCCReg(regRelIdx);
+ values[Lo] = thread->readCCReg(regRelIdx);
}
void
@@ -235,7 +235,7 @@ TarmacTracerRecord::TraceRegEntry::updateFloat(
regValid = true;
regName = "f" + std::to_string(regRelIdx);
- valueLo = bitsToFloat32(thread->readFloatReg(regRelIdx));
+ values[Lo] = bitsToFloat32(thread->readFloatReg(regRelIdx));
}
void
@@ -275,7 +275,7 @@ TarmacTracerRecord::TraceRegEntry::updateInt(
regName = "r" + std::to_string(regRelIdx);
break;
}
- valueLo = thread->readIntReg(regRelIdx);
+ values[Lo] = thread->readIntReg(regRelIdx);
}
void
@@ -451,7 +451,7 @@ TarmacTracerRecord::TraceRegEntry::print(
ccprintf(outs, "%s clk R %s %08x\n",
curTick(), /* Tick time */
regName, /* Register name */
- valueLo); /* Register value */
+ values[Lo]); /* Register value */
}
} // namespace Trace
diff --git a/src/arch/arm/tracers/tarmac_record_v8.cc b/src/arch/arm/tracers/tarmac_record_v8.cc
index 90f1a6fc3..f17016124 100644
--- a/src/arch/arm/tracers/tarmac_record_v8.cc
+++ b/src/arch/arm/tracers/tarmac_record_v8.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 ARM Limited
+ * Copyright (c) 2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -241,7 +241,7 @@ TarmacTracerRecordV8::TraceRegEntryV8::print(
cpuName, /* Cpu name */
regName, /* Register name */
regWidth >> 2, /* Register value padding */
- valueLo); /* Register value */
+ values[Lo]); /* Register value */
}
}