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/ProgramLoader.cpp
src/ProgramLoader.h
src/components/Alu.cpp
src/components/Alu.h
)

View File

@@ -6,6 +6,8 @@
#include <utility>
#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;
}

View File

@@ -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();
};

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"
Register& Register::getInstance() {
Register::Register() {
m_registers = {0};
}
Register &Register::getInstance() {
static Register instance;
return instance;
}

View File

@@ -11,28 +11,31 @@
class Register {
private:
Register() = default;
Register();
/// Singleton instance
static Register *m_instance;
/// "Echter" Register Speicher
std::array<int, 32> m_registers;
std::array<int, 32> 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