added ALU with first commands

This commit is contained in:
black
2025-07-07 16:56:01 +02:00
parent b456f69fe1
commit 0479b1850a
7 changed files with 118 additions and 10 deletions

View File

@@ -13,4 +13,6 @@ add_executable(riscv_emulator
src/Manager.h src/Manager.h
src/ProgramLoader.cpp src/ProgramLoader.cpp
src/ProgramLoader.h src/ProgramLoader.h
src/components/Alu.cpp
src/components/Alu.h
) )

View File

@@ -6,6 +6,8 @@
#include <utility> #include <utility>
#include "components/Alu.h"
Manager::Manager(std::string path): m_path(std::move(path)) { Manager::Manager(std::string path): m_path(std::move(path)) {
m_programFile.open(path); m_programFile.open(path);
} }
@@ -24,6 +26,7 @@ int Manager::run() {
ProgramLoader::getInstance()->indexFile(m_programFile); ProgramLoader::getInstance()->indexFile(m_programFile);
while (std::getline(m_programFile, line)) { while (std::getline(m_programFile, line)) {
auto lineVector = ProgramLoader::parseLine(line); auto lineVector = ProgramLoader::parseLine(line);
Alu::calculate(lineVector);
} }
return 0; return 0;
} }

View File

@@ -33,12 +33,19 @@ public:
~Manager(); ~Manager();
/** /**
* Gibt die Singleton Instanz des Managers zurück
* *
* @param program_path Der Pfad zur .txt Quelldatei des Programmes * @param program_path Der Pfad des Quellcodes
* @return Manager Instanz * @return Die Singleton Instance des Managers
*/ */
static Manager *getInstance(const std::string &program_path); static Manager *getInstance(const std::string &program_path);
/**
* Die Hauptmethode des Emulators.
* Startet die Ausführung des Quellcodes.
*
* @return Der Exitcode des Emulators
*/
int run(); int run();
}; };

58
src/components/Alu.cpp Normal file
View File

@@ -0,0 +1,58 @@
//
// Created by black on 07.07.25.
//
#include "Alu.h"
#include <vector>
#include "Register.h"
void Alu::calculate(const std::vector<std::string> &commandVector) {
/// Extrahiere den eigentlichen RISC-V Befehl für die ALU
const std::string &command = commandVector.at(0);
/// Extrahiere die Argumente des Befehls
const auto arg1 = parseArgument(commandVector.at(0));
const auto arg2 = parseArgument(commandVector.at(1));
int arg3 = 0;
if (!commandVector.at(2).empty()) {
arg3 = parseArgument(commandVector.at(2));
}
if (command == "add") {
const auto register1 = Register::getInstance().getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3);
const auto result = register1 + register2;
Register::getInstance().setRegister(arg1, result);
} else if (command == "sub") {
const auto register1 = Register::getInstance().getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3);
const auto result = register1 - register2;
Register::getInstance().setRegister(arg1, result);
} else if (command == "and") {
const auto register1 = Register::getInstance().getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3);
const auto result = register1 & register2;
Register::getInstance().setRegister(arg1, result);
} else if (command == "or") {
const auto register1 = Register::getInstance().getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3);
const auto result = register1 | register2;
Register::getInstance().setRegister(arg1, result);
} else if (command == "xor") {
const auto register1 = Register::getInstance().getRegister(arg2);
const auto register2 = Register::getInstance().getRegister(arg3);
const auto result = register1 ^ register2;
Register::getInstance().setRegister(arg1, result);
}
}
int Alu::parseArgument(std::string argument) {
/// Falls das erste Argument ein Register ist, entferne das führende "x"
if (argument.at(0) == 'x') {
argument = argument.substr(1, argument.length() - 1);
}
/// Da das Argument noch als String vorliegt, muss es in ein int umgewandelt werden
return std::stoi(argument);
}

32
src/components/Alu.h Normal file
View File

@@ -0,0 +1,32 @@
//
// Created by black on 07.07.25.
//
#ifndef ALU_H
#define ALU_H
#include <string>
#include <vector>
class Alu {
public:
/**
* Die Hauptmethode der ALU.
* Führt die eigentlichen Berechnungen aus.
*
* @param commandVector Die auszuführende Codezeile
*/
static void calculate(const std::vector<std::string> &commandVector);
/**
* Wandelt das gegebene Befehlsargument in ein Integer um
* und entfernt dabei ein mögliches "x" vor Registern.
*
* @param argument Das Befehlsargument, welches geparst werden soll
* @return Das Befehlsargument als int
*/
static int parseArgument(std::string argument);
};
#endif //ALU_H

View File

@@ -5,7 +5,11 @@
#include "Register.h" #include "Register.h"
Register& Register::getInstance() { Register::Register() {
m_registers = {0};
}
Register &Register::getInstance() {
static Register instance; static Register instance;
return instance; return instance;
} }

View File

@@ -11,28 +11,31 @@
class Register { class Register {
private: private:
Register() = default; Register();
/// Singleton instance /// Singleton instance
static Register *m_instance; static Register *m_instance;
/// "Echter" Register Speicher /// "Echter" Register Speicher
std::array<int, 32> m_registers; std::array<int, 32> m_registers{};
public: public:
/// Singleton Logik /// Singleton Logik
Register(const Register &) = delete; Register(const Register &) = delete;
Register(const Register &&) = delete; Register(const Register &&) = delete;
Register& operator=(const Register &) = delete;
Register& operator=(const Register &&) = delete; Register &operator=(const Register &) = delete;
Register &operator=(const Register &&) = delete;
~Register() = default; ~Register() = default;
/** /**
* *
* @return Register Instanz * @return Register Instanz
*/ */
static Register& getInstance(); static Register &getInstance();
/** /**
* Speichert den angegebenen Wert im angegebenen Register * Speichert den angegebenen Wert im angegebenen Register
@@ -48,7 +51,6 @@ public:
* @return Der Wert des Registers * @return Der Wert des Registers
*/ */
int getRegister(int reg) const; int getRegister(int reg) const;
}; };
#endif //REGISTER_H #endif //REGISTER_H