From 239835d4246cc5e2c13892c19a4b79e0cc034393 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Mon, 30 Sep 2019 16:14:02 +0100 Subject: [PATCH] arch-arm: Provide SVE support to the TarmacTracer Change-Id: I86ff5f49a0c0aa126d53076964f208716e70aacb Signed-off-by: Giacomo Travaglini Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21561 Reviewed-by: Ciro Santilli Tested-by: kokoro --- src/arch/arm/tracers/tarmac_record.cc | 6 ++ src/arch/arm/tracers/tarmac_record.hh | 8 ++- src/arch/arm/tracers/tarmac_record_v8.cc | 82 +++++++++++++++++++++++- src/arch/arm/tracers/tarmac_record_v8.hh | 20 +++++- 4 files changed, 110 insertions(+), 6 deletions(-) diff --git a/src/arch/arm/tracers/tarmac_record.cc b/src/arch/arm/tracers/tarmac_record.cc index d3df6895c..3acc32f5f 100644 --- a/src/arch/arm/tracers/tarmac_record.cc +++ b/src/arch/arm/tracers/tarmac_record.cc @@ -178,6 +178,12 @@ TarmacTracerRecord::TraceRegEntry::update( case MiscRegClass: updateMisc(tarmCtx, regRel); break; + case VecRegClass: + updateVec(tarmCtx, regRel); + break; + case VecPredRegClass: + updatePred(tarmCtx, regRel); + break; default: // If unsupported format, do nothing: non updating // the register will prevent it to be printed. diff --git a/src/arch/arm/tracers/tarmac_record.hh b/src/arch/arm/tracers/tarmac_record.hh index d2534732c..8c43de40c 100644 --- a/src/arch/arm/tracers/tarmac_record.hh +++ b/src/arch/arm/tracers/tarmac_record.hh @@ -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 @@ -149,6 +149,12 @@ class TarmacTracerRecord : public TarmacBaseRecord virtual void updateInt(const TarmacContext& tarmCtx, RegIndex regRelIdx); + virtual void + updateVec(const TarmacContext& tarmCtx, RegIndex regRelIdx) {}; + + virtual void + updatePred(const TarmacContext& tarmCtx, RegIndex regRelIdx) {}; + public: /** True if register entry is valid */ bool regValid; diff --git a/src/arch/arm/tracers/tarmac_record_v8.cc b/src/arch/arm/tracers/tarmac_record_v8.cc index f17016124..5193b7fe9 100644 --- a/src/arch/arm/tracers/tarmac_record_v8.cc +++ b/src/arch/arm/tracers/tarmac_record_v8.cc @@ -125,6 +125,59 @@ TarmacTracerRecordV8::TraceRegEntryV8::updateMisc( regWidth = 32; } +void +TarmacTracerRecordV8::TraceRegEntryV8::updateVec( + const TarmacContext& tarmCtx, + RegIndex regRelIdx +) +{ + auto thread = tarmCtx.thread; + const auto& vec_container = thread->readVecReg( + RegId(regClass, regRelIdx)); + auto vv = vec_container.as(); + + regWidth = ArmStaticInst::getCurSveVecLenInBits(thread); + auto num_elements = regWidth / (sizeof(VecElem) * 8); + + // Resize vector of values + values.resize(num_elements); + + for (auto i = 0; i < num_elements; i++) { + values[i] = vv[i]; + } + + regValid = true; + regName = "Z" + std::to_string(regRelIdx); +} + +void +TarmacTracerRecordV8::TraceRegEntryV8::updatePred( + const TarmacContext& tarmCtx, + RegIndex regRelIdx +) +{ + auto thread = tarmCtx.thread; + const auto& pred_container = thread->readVecPredReg( + RegId(regClass, regRelIdx)); + + // Predicate registers are always 1/8 the size of related vector + // registers. (getCurSveVecLenInBits(thread) / 8) + regWidth = ArmStaticInst::getCurSveVecLenInBits(thread) / 8; + auto num_elements = regWidth / 16; + + // Resize vector of values + values.resize(num_elements); + + // Get a copy of pred_container as a vector of half-words + auto vv = pred_container.as(); + for (auto i = 0; i < num_elements; i++) { + values[i] = vv[i]; + } + + regValid = true; + regName = "P" + std::to_string(regRelIdx); +} + void TarmacTracerRecordV8::addInstEntry(std::vector& queue, const TarmacContext& tarmCtx) @@ -236,12 +289,35 @@ TarmacTracerRecordV8::TraceRegEntryV8::print( // Print the register record formatted according // to the Tarmac specification if (regValid) { - ccprintf(outs, "%s clk %s R %s %0*x\n", + ccprintf(outs, "%s clk %s R %s %s\n", curTick(), /* Tick time */ cpuName, /* Cpu name */ regName, /* Register name */ - regWidth >> 2, /* Register value padding */ - values[Lo]); /* Register value */ + formatReg()); /* Register value */ + } +} + +std::string +TarmacTracerRecordV8::TraceRegEntryV8::formatReg() const +{ + if (regWidth <= 64) { + // Register width is < 64 bit (scalar register). + return csprintf("%0*x", regWidth / 4, values[Lo]); + } else { + + // Register width is > 64 bit (vector). Iterate over every vector + // element. Since the vector values are stored in Little Endian, print + // starting from the last element. + std::string reg_val; + for (auto it = values.rbegin(); it != values.rend(); it++) { + reg_val += csprintf("%0*x_", + static_cast(sizeof(VecElem) * 2), *it); + } + + // Remove trailing underscore + reg_val.pop_back(); + + return reg_val; } } diff --git a/src/arch/arm/tracers/tarmac_record_v8.hh b/src/arch/arm/tracers/tarmac_record_v8.hh index a727ea6a6..8743b61da 100644 --- a/src/arch/arm/tracers/tarmac_record_v8.hh +++ b/src/arch/arm/tracers/tarmac_record_v8.hh @@ -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 @@ -108,7 +108,23 @@ class TarmacTracerRecordV8 : public TarmacTracerRecord void updateMisc(const TarmacContext& tarmCtx, RegIndex regRelIdx) override; - uint8_t regWidth; + void updateVec(const TarmacContext& tarmCtx, + RegIndex regRelIdx) override; + + void updatePred(const TarmacContext& tarmCtx, + RegIndex regRelIdx) override; + + /** + * Returning a string which contains the formatted + * register value: transformed in hex, 0 padded or/and + * split in chunks separated by underscores in case of + * vector register. + * @return str formatted string + */ + std::string formatReg() const; + + /** Size in bits of arch register */ + uint16_t regWidth; }; /** -- 2.30.2