changed "///" to "//" in comments
This commit is contained in:
@@ -13,24 +13,24 @@
|
||||
#include "../ProgramLoader.h"
|
||||
|
||||
void Alu::calculate(const std::vector<std::string> &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<std::string> &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<std::string> &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<int>(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<int>(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<std::string> &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;
|
||||
}
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
#define MEMORY_H
|
||||
#include <array>
|
||||
|
||||
/// 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<int, 8192> m_memory{};
|
||||
|
||||
public:
|
||||
/// Singleton Logik
|
||||
// Singleton Logik
|
||||
Memory(const Memory &) = delete;
|
||||
|
||||
Memory(const Memory &&) = delete;
|
||||
|
||||
@@ -6,21 +6,21 @@
|
||||
#define REGISTER_H
|
||||
#include <array>
|
||||
|
||||
/// 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<int, 32> m_registers{};
|
||||
|
||||
public:
|
||||
/// Singleton Logik
|
||||
// Singleton Logik
|
||||
Register(const Register &) = delete;
|
||||
|
||||
Register(const Register &&) = delete;
|
||||
|
||||
Reference in New Issue
Block a user