From 0479b1850ad80d67d61a92d4a0d5fa3abadddf8d Mon Sep 17 00:00:00 2001 From: black Date: Mon, 7 Jul 2025 16:56:01 +0200 Subject: [PATCH] added ALU with first commands --- CMakeLists.txt | 2 ++ src/Manager.cpp | 3 ++ src/Manager.h | 11 +++++-- src/components/Alu.cpp | 58 +++++++++++++++++++++++++++++++++++++ src/components/Alu.h | 32 ++++++++++++++++++++ src/components/Register.cpp | 6 +++- src/components/Register.h | 16 +++++----- 7 files changed, 118 insertions(+), 10 deletions(-) create mode 100644 src/components/Alu.cpp create mode 100644 src/components/Alu.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e193693..a5b9f3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,4 +13,6 @@ add_executable(riscv_emulator src/Manager.h src/ProgramLoader.cpp src/ProgramLoader.h + src/components/Alu.cpp + src/components/Alu.h ) diff --git a/src/Manager.cpp b/src/Manager.cpp index 03b098b..6caeaa1 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -6,6 +6,8 @@ #include +#include "components/Alu.h" + Manager::Manager(std::string path): m_path(std::move(path)) { m_programFile.open(path); } @@ -24,6 +26,7 @@ int Manager::run() { ProgramLoader::getInstance()->indexFile(m_programFile); while (std::getline(m_programFile, line)) { auto lineVector = ProgramLoader::parseLine(line); + Alu::calculate(lineVector); } return 0; } diff --git a/src/Manager.h b/src/Manager.h index 7e006fd..cca103f 100644 --- a/src/Manager.h +++ b/src/Manager.h @@ -33,12 +33,19 @@ public: ~Manager(); /** + * Gibt die Singleton Instanz des Managers zurück * - * @param program_path Der Pfad zur .txt Quelldatei des Programmes - * @return Manager Instanz + * @param program_path Der Pfad des Quellcodes + * @return Die Singleton Instance des Managers */ 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(); }; diff --git a/src/components/Alu.cpp b/src/components/Alu.cpp new file mode 100644 index 0000000..fbbf213 --- /dev/null +++ b/src/components/Alu.cpp @@ -0,0 +1,58 @@ +// +// Created by black on 07.07.25. +// + +#include "Alu.h" + +#include + +#include "Register.h" + +void Alu::calculate(const std::vector &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); +} diff --git a/src/components/Alu.h b/src/components/Alu.h new file mode 100644 index 0000000..9abc454 --- /dev/null +++ b/src/components/Alu.h @@ -0,0 +1,32 @@ +// +// Created by black on 07.07.25. +// + +#ifndef ALU_H +#define ALU_H +#include +#include + + +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 &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 diff --git a/src/components/Register.cpp b/src/components/Register.cpp index 4d361ec..c5a3a5d 100644 --- a/src/components/Register.cpp +++ b/src/components/Register.cpp @@ -5,7 +5,11 @@ #include "Register.h" -Register& Register::getInstance() { +Register::Register() { + m_registers = {0}; +} + +Register &Register::getInstance() { static Register instance; return instance; } diff --git a/src/components/Register.h b/src/components/Register.h index 7a2d035..874c46d 100644 --- a/src/components/Register.h +++ b/src/components/Register.h @@ -11,28 +11,31 @@ class Register { - private: - Register() = default; + Register(); /// Singleton instance static Register *m_instance; /// "Echter" Register Speicher - std::array m_registers; + std::array m_registers{}; public: /// Singleton Logik 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; /** * * @return Register Instanz */ - static Register& getInstance(); + static Register &getInstance(); /** * Speichert den angegebenen Wert im angegebenen Register @@ -48,7 +51,6 @@ public: * @return Der Wert des Registers */ int getRegister(int reg) const; - }; #endif //REGISTER_H