Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor Feature Fixes #240

Merged
merged 15 commits into from
Sep 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions src/include/simeng/Core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ class Core {

/** Retrieve a map of statistics to report. */
virtual std::map<std::string, std::string> getStats() const = 0;

/** Increment value of the Virtual Counter Timer system register. */
virtual void incVCT(uint64_t iterations) = 0;

/** Change the value of the Processor Cycle Counter system register to number
* of cycles completed. */
virtual void updatePCC(uint64_t iterations) = 0;
};

} // namespace simeng
2 changes: 1 addition & 1 deletion src/include/simeng/ModelConfig.hh
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class ModelConfig {

/** Given a node, value requirements, and possibly a deafult value,
* validate the value held within the node. All methods perform, at
* least, an existance and "read as type" check with the latter
* least, an existence and "read as type" check with the latter
* reading the value as the given type within a try catch
* expressions. */
// Set of values requirement, no default value
Expand Down
3 changes: 1 addition & 2 deletions src/include/simeng/SpecialFileDirGen.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class SpecialFileDirGen {

private:
/** Path to the root of the SimEng special files directory. */
const std::string specialFilesDir_ =
SIMENG_SOURCE_DIR "/src/lib/kernel/specialFiles";
const std::string specialFilesDir_ = SIMENG_BUILD_DIR "/specialFiles";

/** Values declared in YAML config file needed to create the Special Files
* Directory tree. */
Expand Down
8 changes: 3 additions & 5 deletions src/include/simeng/arch/Architecture.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,9 @@ class Architecture {
/** Returns the maximum size of a valid instruction in bytes. */
virtual uint8_t getMaxInstructionSize() const = 0;

/** Returns the system register for the Virtual Counter Timer. */
virtual simeng::Register getVCTreg() const = 0;

/** Returns the system register for the Processor Cycle Counter. */
virtual simeng::Register getPCCreg() const = 0;
/** Updates System registers of any system-based timers. */
virtual void updateSystemTimerRegisters(RegisterFileSet* regFile,
const uint64_t iterations) const = 0;
};

} // namespace arch
Expand Down
18 changes: 13 additions & 5 deletions src/include/simeng/arch/aarch64/Architecture.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,9 @@ class Architecture : public arch::Architecture {
/** Returns the current vector length set by the provided configuration. */
uint64_t getVectorLength() const;

/** Returns the system register for the Virtual Counter Timer. */
simeng::Register getVCTreg() const override;

/** Returns the system register for the Processor Cycle Counter. */
simeng::Register getPCCreg() const override;
/** Updates System registers of any system-based timers. */
void updateSystemTimerRegisters(RegisterFileSet* regFile,
const uint64_t iterations) const override;

/** Retrieve an ExecutionInfo object for the requested instruction. If a
* opcode-based override has been defined for the latency and/or
Expand Down Expand Up @@ -98,6 +96,16 @@ class Architecture : public arch::Architecture {

/** The vector length used by the SVE extension in bits. */
uint64_t VL_;

/** System Register of Virtual Counter Timer. */
simeng::Register VCTreg_;

/** System Register of Processor Cycle Counter. */
simeng::Register PCCreg_;

/** Modulo component used to define the frequency at which the VCT is updated.
*/
double vctModulo_;
};

} // namespace aarch64
Expand Down
24 changes: 14 additions & 10 deletions src/include/simeng/arch/aarch64/helpers/auxiliaryFunctions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,22 @@ class AuxFunc {
static uint16_t sveGetPattern(const std::string operandStr,
const uint8_t esize, const uint16_t VL_) {
const uint16_t elements = VL_ / esize;
// If not pattern then same as ALL
if (operandStr.find(",") == std::string::npos) return elements;

// Get pattern string
std::string pattern(operandStr.substr(operandStr.find(",") + 2));
if (pattern.find(',') != std::string::npos) {
pattern.erase(pattern.find(","));
const std::vector<std::string> patterns = {
jj16791 marked this conversation as resolved.
Show resolved Hide resolved
"pow2", "vl1", "vl2", "vl3", "vl4", "vl5", "vl6", "vl7", "vl8",
"vl16", "vl32", "vl64", "vl128", "vl256", "mul3", "mul4", "all"};

// If no pattern present in operandStr then same behaviour as ALL
std::string pattern = "all";
for (uint8_t i = 0; i < patterns.size(); i++) {
if (operandStr.find(patterns[i]) != std::string::npos) {
pattern = patterns[i];
// Don't break when pattern found as vl1 will be found in vl128 etc
}
}

if (pattern == "pow2") {
if (pattern == "all")
return elements;
else if (pattern == "pow2") {
int n = 1;
while (elements >= std::pow(2, n)) {
n = n + 1;
Expand Down Expand Up @@ -310,8 +316,6 @@ class AuxFunc {
return elements - (elements % 4);
else if (pattern == "mul3")
return elements - (elements % 3);
else if (pattern == "all")
return elements;

return 0;
}
Expand Down
8 changes: 6 additions & 2 deletions src/include/simeng/arch/aarch64/helpers/sve.hh
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,8 @@ class sveHelp {
// Get pattern
const uint16_t count =
AuxFunc::sveGetPattern(metadata.operandStr, sizeof(T) * 8, VL_bits);
// Exit early if count == 0
if (count == 0) return out;

for (int i = 0; i < partition_num; i++) {
if (i < count) {
Expand Down Expand Up @@ -1479,15 +1481,17 @@ class sveHelp {
const uint16_t VL_bits) {
const D d = operands[0].get<D>();
const uint8_t imm = metadata.operands[1].imm;
const uint16_t count =
AuxFunc::sveGetPattern(metadata.operandStr, N, VL_bits);

// The range of possible values does not fit in the range of any integral
// type, so a double is used as an intermediate value. The end result must
// be saturated to fit in uint64_t.
auto intermediate = double(d) - (imm * (VL_bits / N));
auto intermediate = double(d) - (imm * count);
if (intermediate < 0) {
return (uint64_t)0;
}
return (uint64_t)(d - (imm * (VL_bits / N)));
return (uint64_t)(d - (imm * count));
}

/** Helper function for SVE instructions with the format `uzp<1,2> zd, zn,
Expand Down
13 changes: 0 additions & 13 deletions src/include/simeng/models/emulation/Core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,6 @@ class Core : public simeng::Core {
/** Retrieve a map of statistics to report. */
std::map<std::string, std::string> getStats() const override;

/** Increment value of the Virtual Counter Timer system register. */
void incVCT(uint64_t iterations) override;

/** Change the value of the Processor Cycle Counter system register to number
* of cycles completed. */
void updatePCC(uint64_t iterations) override;

private:
/** Execute an instruction. */
void execute(std::shared_ptr<Instruction>& uop);
Expand Down Expand Up @@ -112,12 +105,6 @@ class Core : public simeng::Core {

/** The number of branches executed. */
uint64_t branchesExecuted_ = 0;

/** System Register of Virtual Counter Timer. */
simeng::Register VCTreg_;

/** System Register of Processor Cycle Counter. */
simeng::Register PCCreg_;
};

} // namespace emulation
Expand Down
13 changes: 0 additions & 13 deletions src/include/simeng/models/inorder/Core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ class Core : public simeng::Core {
/** Generate a map of statistics to report. */
std::map<std::string, std::string> getStats() const override;

/** Increment value of the Virtual Counter Timer system register. */
void incVCT(uint64_t iterations) override;

/** Change the value of the Processor Cycle Counter system register to number
* of cycles completed. */
void updatePCC(uint64_t iterations) override;

private:
/** Raise an exception to the core, providing the generating instruction. */
void raiseException(const std::shared_ptr<Instruction>& instruction);
Expand Down Expand Up @@ -139,12 +132,6 @@ class Core : public simeng::Core {

/** The active exception handler. */
std::shared_ptr<arch::ExceptionHandler> exceptionHandler_;

/** System Register of Virtual Counter Timer. */
simeng::Register VCTreg_;

/** System Register of Processor Cycle Counter. */
simeng::Register PCCreg_;
};

} // namespace inorder
Expand Down
13 changes: 0 additions & 13 deletions src/include/simeng/models/outoforder/Core.hh
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,6 @@ class Core : public simeng::Core {
/** Generate a map of statistics to report. */
std::map<std::string, std::string> getStats() const override;

/** Increment value of the Virtual Counter Timer system register. */
void incVCT(uint64_t iterations) override;

/** Change the value of the Processor Cycle Counter system register to number
* of cycles completed. */
void updatePCC(uint64_t iterations) override;

private:
/** Raise an exception to the core, providing the generating instruction. */
void raiseException(const std::shared_ptr<Instruction>& instruction);
Expand Down Expand Up @@ -169,12 +162,6 @@ class Core : public simeng::Core {

/** The active exception handler. */
std::shared_ptr<arch::ExceptionHandler> exceptionHandler_;

/** System Register of Virtual Counter Timer. */
simeng::Register VCTreg_;

/** System Register of Processor Cycle Counter. */
simeng::Register PCCreg_;
};

} // namespace outoforder
Expand Down
1 change: 1 addition & 0 deletions src/include/simeng/version.hh.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
#define SIMENG_SOURCE_DIR "${PROJECT_SOURCE_DIR}"
#define SIMENG_LLVM_VERSION @SIMENG_LLVM_VERSION@
#define SIMENG_ENABLE_TESTS "${SIMENG_ENABLE_TESTS}"
#define SIMENG_BUILD_DIR "${CMAKE_BINARY_DIR}"

#endif
4 changes: 3 additions & 1 deletion src/lib/GenericPredictor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ BranchPrediction GenericPredictor::predict(uint64_t address, BranchType type,
BranchPrediction prediction = {direction, target};

// Ammend prediction based on branch type
if (type == BranchType::Unconditional || type == BranchType::LoopClosing) {
if (type == BranchType::Unconditional) {
prediction.taken = true;
} else if (type == BranchType::Return) {
prediction.taken = true;
Expand All @@ -60,6 +60,8 @@ BranchPrediction GenericPredictor::predict(uint64_t address, BranchType type,
ras_.push_back(address + 4);
// Record that this address is a branch-and-link instruction
rasHistory_[address] = 0;
} else if (type == BranchType::Conditional) {
if (!prediction.taken) prediction.target = address + 4;
}
return prediction;
}
Expand Down
14 changes: 7 additions & 7 deletions src/lib/ModelConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void ModelConfig::validate() {
char port_msg[10];
sprintf(port_msg, "Port %zu ", i);
std::string port_num = std::string(port_msg);
// Check for existance of Portname field and record name
// Check for existence of Portname field and record name
if (nodeChecker<std::string>(port_node["Portname"], port_num + "Portname",
std::vector<std::string>{},
ExpectedValue::String)) {
Expand All @@ -195,7 +195,7 @@ void ModelConfig::validate() {
<< "\" already used\n";
}
}
// Check for existance of Instruction-Support field
// Check for existence of Instruction-Support field
if (!(port_node["Instruction-Support"].IsDefined()) ||
port_node["Instruction-Support"].IsNull()) {
missing_ << "\t- " << port_num << "Instruction-Support\n";
Expand Down Expand Up @@ -248,7 +248,7 @@ void ModelConfig::validate() {
nodeChecker<uint16_t>(rs["Size"], rs_num + "Size",
std::make_pair(1, UINT16_MAX),
ExpectedValue::UInteger);
// Check for existance of Ports field
// Check for existence of Ports field
if (!(rs["Ports"].IsDefined()) || rs["Ports"].IsNull()) {
missing_ << "\t- " << rs_num << "Ports\n";
continue;
Expand Down Expand Up @@ -597,7 +597,7 @@ template <typename T>
int ModelConfig::nodeChecker(const YAML::Node& node, const std::string& field,
const std::vector<T>& value_set,
uint8_t expected) {
// Check for the existance of the given node
// Check for the existence of the given node
if (!(node.IsDefined()) || node.IsNull()) {
missing_ << "\t- " << field << "\n";
return 0;
Expand All @@ -610,7 +610,7 @@ template <typename T>
int ModelConfig::nodeChecker(YAML::Node node, const std::string& field,
const std::vector<T>& value_set, uint8_t expected,
T default_value) {
// Check for the existance of the given node
// Check for the existence of the given node
if (!(node.IsDefined()) || node.IsNull()) {
node = default_value;
return 1;
Expand All @@ -622,7 +622,7 @@ int ModelConfig::nodeChecker(YAML::Node node, const std::string& field,
template <typename T>
int ModelConfig::nodeChecker(const YAML::Node& node, const std::string& field,
const std::pair<T, T>& bounds, uint8_t expected) {
// Check for the existance of the given node
// Check for the existence of the given node
if (!(node.IsDefined()) || node.IsNull()) {
missing_ << "\t- " << field << "\n";
return 0;
Expand All @@ -635,7 +635,7 @@ template <typename T>
int ModelConfig::nodeChecker(YAML::Node node, const std::string& field,
const std::pair<T, T>& bounds, uint8_t expected,
const T& default_value) {
// Check for the existance of the given node
// Check for the existence of the given node
if (!(node.IsDefined()) || node.IsNull()) {
node = default_value;
return 1;
Expand Down
28 changes: 19 additions & 9 deletions src/lib/arch/aarch64/Architecture.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ std::forward_list<InstructionMetadata> Architecture::metadataCache;
Architecture::Architecture(kernel::Linux& kernel, YAML::Node config)
: linux_(kernel),
microDecoder_(std::make_unique<MicroDecoder>(config)),
VL_(config["Core"]["Vector-Length"].as<uint64_t>()) {
VL_(config["Core"]["Vector-Length"].as<uint64_t>()),
vctModulo_((config["Core"]["Clock-Frequency"].as<float>() * 1e9) /
(config["Core"]["Timer-Frequency"].as<uint32_t>() * 1e6)) {
if (cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &capstoneHandle) != CS_ERR_OK) {
std::cerr << "Could not create capstone handle" << std::endl;
exit(1);
Expand All @@ -30,6 +32,14 @@ Architecture::Architecture(kernel::Linux& kernel, YAML::Node config)
systemRegisterMap_[ARM64_SYSREG_CNTVCT_EL0] = systemRegisterMap_.size();
systemRegisterMap_[ARM64_SYSREG_PMCCNTR_EL0] = systemRegisterMap_.size();

// Get Virtual Counter Timer and Processor Cycle Counter system registers.
VCTreg_ = {
RegisterType::SYSTEM,
static_cast<uint16_t>(getSystemRegisterTag(ARM64_SYSREG_CNTVCT_EL0))};
PCCreg_ = {
RegisterType::SYSTEM,
static_cast<uint16_t>(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))};

// Instantiate an ExecutionInfo entry for each group in the InstructionGroup
// namespace.
for (int i = 0; i < NUM_GROUPS; i++) {
Expand Down Expand Up @@ -267,15 +277,15 @@ uint8_t Architecture::getMaxInstructionSize() const { return 4; }

uint64_t Architecture::getVectorLength() const { return VL_; }

simeng::Register Architecture::getVCTreg() const {
return {RegisterType::SYSTEM,
static_cast<uint16_t>(getSystemRegisterTag(ARM64_SYSREG_CNTVCT_EL0))};
}
void Architecture::updateSystemTimerRegisters(RegisterFileSet* regFile,
const uint64_t iterations) const {
// Update the Processor Cycle Counter to total cycles completed.
regFile->set(PCCreg_, iterations);

simeng::Register Architecture::getPCCreg() const {
return {
RegisterType::SYSTEM,
static_cast<uint16_t>(getSystemRegisterTag(ARM64_SYSREG_PMCCNTR_EL0))};
// Update Virtual Counter Timer at correct frequency.
if (iterations % (uint64_t)vctModulo_ == 0) {
regFile->set(VCTreg_, regFile->get(VCTreg_).get<uint64_t>() + 1);
}
}

} // namespace aarch64
Expand Down
5 changes: 3 additions & 2 deletions src/lib/arch/aarch64/Instruction_execute.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7769,9 +7769,10 @@ void Instruction::execute() {
uint64_t mini[2] = {0};
for (int i = 0; i < 2; i++) {
uint64_t shifted_active = 1ull << ((i % 8) * 8);
if (p[i / 8] & shifted_active)
if (p[i / 8] & shifted_active) {
mini[i] = memoryData[index].get<uint64_t>();
index++;
index++;
}
}

// Duplicate mini-vector into output vector
Expand Down
Loading