diff --git a/src/components/Alu.cpp b/src/components/Alu.cpp index 6e60b90..8b664d8 100644 --- a/src/components/Alu.cpp +++ b/src/components/Alu.cpp @@ -13,24 +13,24 @@ #include "../ProgramLoader.h" void Alu::calculate(const std::vector &commandVector) { - /// Falls die aktuelle Zeile ein Label ist, return + // 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 + // Extrahiere den eigentlichen RISC-V Befehl für die ALU const std::string &command = commandVector.at(0); - /// Extrahiere die Argumente des Befehls + // Extrahiere die Argumente des Befehls const auto arg1 = parseArgument(commandVector.at(1)); - /// Wandle Vektor[2] (das zweite Argument) nur um, falls es kein SW/LW Argument ist + // Wandle Vektor[2] (das zweite Argument) nur um, falls es kein SW/LW Argument ist int arg2 = 0; if (commandVector.at(2).find('(') != std::string::npos) { arg2 = parseAddress(commandVector.at(2)); } else { arg2 = parseArgument(commandVector.at(2)); } - /// Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert und kein immediate Wert ist + // Wandle Vektor[3] (das dritte Argument) nur um, falls dieser existiert und kein immediate Wert ist int arg3 = 0; if (commandVector.size() > 3) { if (const std::string &arg = commandVector.at(3); isRegister(arg) || isImmediate(arg)) { @@ -39,82 +39,82 @@ void Alu::calculate(const std::vector &commandVector) { } if (command == "add") { - /// Addition Befehl - /// Hole die Werte beider angegebener Register + // Addition Befehl + // Hole die Werte beider angegebener Register const auto register1 = Register::getInstance().getRegister(arg2); const auto register2 = Register::getInstance().getRegister(arg3); - /// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück + // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 + register2; Register::getInstance().setRegister(arg1, result); } else if (command == "sub") { - /// Subtraktion Befehl - /// Hole die Werte beider angegebener Register + // Subtraktion Befehl + // Hole die Werte beider angegebener Register const auto register1 = Register::getInstance().getRegister(arg2); const auto register2 = Register::getInstance().getRegister(arg3); - /// Subtrahiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück + // Subtrahiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 - register2; Register::getInstance().setRegister(arg1, result); } else if (command == "and") { - /// Binärer und Befehl - /// Hole die Werte beider angegebener Register + // Binärer und Befehl + // Hole die Werte beider angegebener Register const auto register1 = Register::getInstance().getRegister(arg2); const auto register2 = Register::getInstance().getRegister(arg3); - /// Verknüpfe die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück + // Verknüpfe die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 & register2; Register::getInstance().setRegister(arg1, result); } else if (command == "or") { - /// Binärer oder Befehl - /// Hole die Werte beider angegebener Register + // Binärer oder Befehl + // Hole die Werte beider angegebener Register const auto register1 = Register::getInstance().getRegister(arg2); const auto register2 = Register::getInstance().getRegister(arg3); - /// Unterscheide die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück + // Unterscheide die beiden Werte binär und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 | register2; Register::getInstance().setRegister(arg1, result); } else if (command == "xor") { - /// Binärer exklusiver oder Befehl - /// Hole die Werte beider angegebener Register + // Binärer exklusiver oder Befehl + // Hole die Werte beider angegebener Register const auto register1 = Register::getInstance().getRegister(arg2); const auto register2 = Register::getInstance().getRegister(arg3); - /// Unterscheide die beiden Werte binär exklusiv und schreibe das Ergebnis ins angegebene Register zurück + // Unterscheide die beiden Werte binär exklusiv und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 ^ register2; Register::getInstance().setRegister(arg1, result); } else if (command == "addi") { - /// Immediate und Befehl - /// Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument + // Immediate und Befehl + // Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument const auto register1 = Register::getInstance().getRegister(arg2); const auto immediate = arg3; - /// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück + // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 + immediate; Register::getInstance().setRegister(arg1, result); } else if (command == "andi") { - /// Binärer immediate und Befehl - /// Hole Wert1 aus dem angegebnen Register und Wert2 aus dem Befehlsargument + // Binärer immediate und Befehl + // Hole Wert1 aus dem angegebnen Register und Wert2 aus dem Befehlsargument const auto register1 = Register::getInstance().getRegister(arg2); const auto immediate = arg3; - /// Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück + // Addiere die beiden Werte und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 & immediate; Register::getInstance().setRegister(arg1, result); } else if (command == "ori") { - /// Binärer immediate oder Befehl - /// Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument + // Binärer immediate oder Befehl + // Hole Wert1 aus dem angegebenen Register und Wert2 aus dem Befehlsargument const auto register1 = Register::getInstance().getRegister(arg2); const auto immediate = arg3; - /// Unterscheide beide Werte binär und schreibe das Ergebnis ins angegebene Register zurück + // Unterscheide beide Werte binär und schreibe das Ergebnis ins angegebene Register zurück const auto result = register1 | immediate; Register::getInstance().setRegister(arg1, result); } else if (command == "lw") { - /// Loadword Befehl - /// Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem RAM + // Loadword Befehl + // Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem RAM const auto address = arg2; const auto data = Memory::getInstance()->load(address); - /// Speichere die Daten im angegeben Register + // Speichere die Daten im angegeben Register Register::getInstance().setRegister(arg1, data); } else if (command == "sw") { - /// Storeword Befehl - /// Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem Register + // Storeword Befehl + // Hole die Adresse aus dem Befehlsargument und die dazugehörigen Daten aus dem Register const auto address = arg2; const auto data = Register::getInstance().getRegister(arg1); - /// Speichere die Daten im angegeben RAM slot + // Speichere die Daten im angegeben RAM slot Memory::getInstance()->store(address, data); } else if (command == "beq") { const auto register1 = Register::getInstance().getRegister(arg1); @@ -133,23 +133,28 @@ void Alu::calculate(const std::vector &commandVector) { Manager::getInstance()->setStreamPosition(streamPos); } } else if (command == "jal") { - /// Jump and link Befehl - /// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien - /// und führt zu undefiniertem Verhalten !!! + // Jump and link Befehl + // !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien + // und führt zu undefiniertem Verhalten !!! + // Speichert die Position des nächsten Befehls im angegebenen Register const auto pos = static_cast(Manager::getInstance()->getNextStreamLineOffset().operator std::streamoff()); + Register::getInstance().setRegister(arg1, pos); + // Holt sich die Position des angegebenen labels und die stream Position auf diese const auto &label = commandVector.at(2); const auto streamPos = ProgramLoader::getInstance()->getStreamPosition(label); - Register::getInstance().setRegister(arg1, pos); Manager::getInstance()->setStreamPosition(streamPos); } else if (command == "jalr") { - /// Jump and link register Befehl - /// !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien - /// und führt zu undefiniertem Verhalten !!! + // Jump and link register Befehl + // !!! Aufgrund des casts des stream offsets zu int funktioniert das nicht bei großen Quellcode Dateien + // und führt zu undefiniertem Verhalten !!! + // Speichert die Position des nächsten Befehls im angegebenen Register const auto pos = static_cast(Manager::getInstance()->getNextStreamLineOffset().operator std::streamoff()); + Register::getInstance().setRegister(arg1, pos); + // Holt sich die Position des angegebenen labels und das Offset aus dem angegebenen Register const auto &label = commandVector.at(3); const auto streamPosLabel = ProgramLoader::getInstance()->getStreamPosition(label); const auto posOffset = Register::getInstance().getRegister(arg2); - Register::getInstance().setRegister(arg1, pos); + // Setzt die stream Position auf den gegebenen Wert & erhöht sie um den angegebenen Offset Manager::getInstance()->setStreamPosition(streamPosLabel); for (int i = 0; i < posOffset; ++i) { Manager::getInstance()->gotoNextStreamLine(); @@ -158,16 +163,16 @@ void Alu::calculate(const std::vector &commandVector) { } int Alu::parseArgument(std::string argument) { - /// Falls das erste Argument ein Register ist, entferne das führende "x" + // Falls das erste Argument ein Register ist, entferne das führende "x" if (argument.at(0) == 'x') argument = argument.substr(1); - /// Da das Argument noch als String vorliegt, muss es in ein int umgewandelt werden + // Da das Argument noch als String vorliegt, muss es in ein int umgewandelt werden return std::stoi(argument); } int Alu::parseAddress(const std::string &argument) { - /// Finde die Position von '(', trenne die den String dort und - /// addiere die umgewandelten Integer zur Adresse - /// Bsp: 0(x1) + // Finde die Position von '(', trenne die den String dort und + // addiere die umgewandelten Integer zur Adresse + // Bsp: 0(x1) if (const size_t pos = argument.find('('); pos != std::string::npos) { const auto immediate = std::stoi(argument.substr(0, pos + 1)); const auto register1 = std::stoi(argument.substr(pos + 2)); @@ -178,16 +183,16 @@ int Alu::parseAddress(const std::string &argument) { } bool Alu::isRegister(const std::string &argument) { - /// Überprüfe, ob das nichtleere Argument mit 'x' startet + // Überprüfe, ob das nichtleere Argument mit 'x' startet if (argument.empty() || argument.at(0) != 'x') return false; - /// Entfernt das voranstehende 'x' und checkt, ob darauf etwas folgt + // Entfernt das voranstehende 'x' und checkt, ob darauf etwas folgt const std::string numberPart = argument.substr(1); if (numberPart.empty()) return false; - /// Überprüfe, ob alle Zeichen im restlichen Argument Nummern sind + // Überprüfe, ob alle Zeichen im restlichen Argument Nummern sind for (const char c: numberPart) { if (!std::isdigit(c)) return false; } - /// Konvertiere zu int und überprüfe, ob es ein Register zwischen inklusive x0 und x32 ist + // Konvertiere zu int und überprüfe, ob es ein Register zwischen inklusive x0 und x32 ist const int regNum = std::stoi(numberPart); return regNum >= 0 && regNum <= 32; } @@ -195,7 +200,7 @@ bool Alu::isRegister(const std::string &argument) { bool Alu::isImmediate(const std::string &argument) { if (argument.empty()) return false; constexpr size_t start = 0; - /// Überprüfe, ob jedes Zeichen im Argument eine Nummer ista + // Überprüfe, ob jedes Zeichen im Argument eine Nummer ista for (size_t i = start; i < argument.size(); ++i) { if (!std::isdigit(argument.at(i))) return false; } diff --git a/src/components/Memory.h b/src/components/Memory.h index 50ea11c..5a8d737 100644 --- a/src/components/Memory.h +++ b/src/components/Memory.h @@ -6,21 +6,21 @@ #define MEMORY_H #include -/// Eine Hauptspeicherklasse als Singleton implementiert. -/// Als Hauptspeicher wird ein Array genutzt. +// Eine Hauptspeicherklasse als Singleton implementiert. +// Als Hauptspeicher wird ein Array genutzt. class Memory { private: Memory(); - /// Singleton instance + // Singleton instance static Memory *m_instance; - /// Hauptspeicher (hier 32 kB groß) + // Hauptspeicher (hier 32 kB groß) std::array m_memory{}; public: - /// Singleton Logik + // Singleton Logik Memory(const Memory &) = delete; Memory(const Memory &&) = delete; diff --git a/src/components/Register.h b/src/components/Register.h index bbbf88f..decf0ff 100644 --- a/src/components/Register.h +++ b/src/components/Register.h @@ -6,21 +6,21 @@ #define REGISTER_H #include -/// Eine Registerklasse als Singleton implementiert. -/// Als Speicher (Registers) wird ein int Array genutzt. +// Eine Registerklasse als Singleton implementiert. +// Als Speicher (Registers) wird ein int Array genutzt. class Register { private: Register(); - /// Singleton instance + // Singleton instance static Register *m_instance; - /// "Echter" Register Speicher + // "Echter" Register Speicher std::array m_registers{}; public: - /// Singleton Logik + // Singleton Logik Register(const Register &) = delete; Register(const Register &&) = delete;