added "beq" command

This commit is contained in:
black
2025-07-08 15:18:00 +02:00
parent f896f82db8
commit 6e65fe88fc
6 changed files with 76 additions and 32 deletions

View File

@@ -11,7 +11,37 @@
#include "components/Alu.h"
namespace fs = std::filesystem;
Manager::Manager(std::string path): m_path(std::move(path)) {
Manager::~Manager() {
m_programFile.close();
}
Manager *Manager::getInstance() {
static Manager instance;
return &instance;
}
int Manager::run() {
if (!m_programFile.is_open()) {
std::cerr << "Bitte zuerst die init() Methode aufrufen!" << "\n" << std::flush;
}
std::string line;
ProgramLoader::getInstance()->indexFile(m_programFile);
/// Die Position des Streams (virtueller Lesekopf) muss nach dem Indexen wieder zurückgesetzt werden
m_programFile.clear();
m_programFile.seekg(0);
while (std::getline(m_programFile, line)) {
auto lineVector = ProgramLoader::parseLine(line);
Alu::calculate(lineVector);
}
return 0;
}
void Manager::setStreamPosition(const std::streampos pos) {
m_programFile.seekg(pos);
}
void Manager::init(const std::string &program_path) {
m_path = program_path;
std::cout << "Öffne Quellcode Datei: '" << m_path << "'" << "\n" << std::flush;
if (!fs::exists(m_path)) {
std::cerr << "Datei existiert nicht: " << m_path << "\n" << std::flush;
@@ -25,24 +55,3 @@ Manager::Manager(std::string path): m_path(std::move(path)) {
return;
}
}
Manager::~Manager() {
m_programFile.close();
}
Manager *Manager::getInstance(const std::string &program_path) {
static Manager instance{program_path};
return &instance;
}
int Manager::run() {
std::string line;
ProgramLoader::getInstance()->indexFile(m_programFile);
m_programFile.clear();
m_programFile.seekg(0);
while (std::getline(m_programFile, line)) {
auto lineVector = ProgramLoader::parseLine(line);
Alu::calculate(lineVector);
}
return 0;
}

View File

@@ -14,7 +14,7 @@
class Manager {
private:
/// Die Instanz des Managers soll mit einem immutable path zum Programm erstellt werden
explicit Manager(std::string path);
Manager() = default;
std::string m_path;
std::map<std::string, int> m_labels;
@@ -38,7 +38,7 @@ public:
* @param program_path Der Pfad des Quellcodes
* @return Die Singleton Instance des Managers
*/
static Manager *getInstance(const std::string &program_path);
static Manager *getInstance();
/**
* Die Hauptmethode des Emulators.
@@ -47,6 +47,15 @@ public:
* @return Der Exitcode des Emulators
*/
int run();
/**
* Setzt die Position des Streams (virtuellen Lesekopfes) auf die angegebene Position
*
* @param pos Die Position des Lesekopfes
*/
void setStreamPosition(std::streampos pos);
void init(const std::string &program_path);
};

View File

@@ -40,9 +40,13 @@ void ProgramLoader::indexFile(std::ifstream &m_programFile) {
/// Parse Zeile für Zeile
while (std::getline(m_programFile, line)) {
auto lineVector = parseLine(line);
/// Sobald ein Label gefunden wurde, speichere die Zeile
/// Sobald ein Label gefunden wurde, speichere die Position des Streams
if (const auto first = lineVector.begin(); first->at(first->length() - 1) == ':') {
m_labels[first->substr(0, first->length() - 1)] = m_programFile.tellg();
}
}
}
std::streampos ProgramLoader::getStreamPosition(const std::string &label) const {
return m_labels.find(label)->second;
}

View File

@@ -15,9 +15,7 @@ class ProgramLoader {
private:
/**
* Der private Konstruktor für ProgramLoader
*
* @param path Der Pfad zur .txt Quelldatei des Programmes
*/
* */
explicit ProgramLoader() = default;
std::map<std::string, std::streampos> m_labels;
@@ -35,7 +33,6 @@ public:
/**
* Gibt die Singleton Instanz des ProgramLoaders zurück
*
* @param program_path Der Pfad zur .txt Quelldatei des Programmes
* @return ProgramLoader Instanz
*/
static ProgramLoader *getInstance();
@@ -52,6 +49,14 @@ public:
* Durchscucht das aktuelle Programm nach Labeln und speichert diese zusammen mit den Zeilennummern in einer Map
*/
void indexFile(std::ifstream &m_programFile);
/**
* Gibt die Position des Streams (virtuellen Lesekopfes) im aktuellen Quellcode zurück
*
* @param label Das Label, dessen Streamposition zurückgegeben werden soll
* @return Die Streamposition des angegebenen Labels
*/
[[nodiscard]] std::streampos getStreamPosition(const std::string &label) const;
};

View File

@@ -7,8 +7,15 @@
#include "Memory.h"
#include "Register.h"
#include "../Manager.h"
#include "../ProgramLoader.h"
void Alu::calculate(const std::vector<std::string> &commandVector) {
/// Falls die aktuelle Zeile ein Label ist, return
if (const auto length = commandVector.at(0).size(); commandVector.at(0).at(length - 1) == ':') {
return;
}
/// Extrahiere den eigentlichen RISC-V Befehl für die ALU
const std::string &command = commandVector.at(0);
@@ -21,7 +28,7 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
}
/// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert
int arg3 = 0;
if (commandVector.size() > 3) {
if (commandVector.size() > 3 && isdigit(commandVector.at(3).at(1))) {
arg3 = parseArgument(commandVector.at(3));
}
@@ -103,6 +110,14 @@ void Alu::calculate(const std::vector<std::string> &commandVector) {
const auto data = Register::getInstance().getRegister(arg1);
/// Speichere die Daten im angegeben RAM slot
Memory::getInstance()->store(address, data);
} else if (command == "beq") {
const auto register1 = Register::getInstance().getRegister(arg1);
const auto register2 = Register::getInstance().getRegister(arg2);
const auto &label = commandVector.at(3);
const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label);
if (register1 == register2) {
Manager::getInstance()->setStreamPosition(streamPos);
}
}
}

View File

@@ -5,7 +5,9 @@
#include "Manager.h"
int main() {
return Manager::getInstance(
Manager::getInstance()->init(
"/home/black/Nextcloud/Dokumente/Dokumente/Hochschule/2. Semester/Rechnerarchitektur/Projekt/test.txt"
)->run();
);
Manager::getInstance()->run();
return 0;
}