diff options
author | Karel Kočí <cynerd@email.cz> | 2017-11-19 21:23:04 +0100 |
---|---|---|
committer | Karel Kočí <cynerd@email.cz> | 2017-11-19 21:23:04 +0100 |
commit | f0ad502e4651243d6a96194b3393bd460c0f7fc9 (patch) | |
tree | 4f912c24b5943bd93b5a3378df75f9611de6779b /qtmips_machine/instruction.cpp | |
parent | 2c6562fa78e884d66b8c2a306f020101e8803f2e (diff) | |
download | qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.tar.gz qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.tar.bz2 qtmips-f0ad502e4651243d6a96194b3393bd460c0f7fc9.zip |
Another huge pile of work for about two months
Well I should commit every change instead of this madness. I am not
documenting changes as all this is just improvements and implementation
progression.
Diffstat (limited to 'qtmips_machine/instruction.cpp')
-rw-r--r-- | qtmips_machine/instruction.cpp | 148 |
1 files changed, 76 insertions, 72 deletions
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp index 1771afb..8591d93 100644 --- a/qtmips_machine/instruction.cpp +++ b/qtmips_machine/instruction.cpp @@ -1,102 +1,106 @@ #include "instruction.h" #include "qtmipsexception.h" -Instruction::Instruction() { - this->st = IS_FETCH; +struct InstructionMap { + const char *name; +}; + +#define IM_UNKNOWN {"UNKNOWN"} +const struct InstructionMap instruction_map[] = { + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + {"ADDI"}, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN, + IM_UNKNOWN +}; + +Instruction::Instruction(std::uint32_t inst) { + this->dt = inst; +} + +Instruction::Instruction(std::uint8_t opcode, std::uint8_t rs, std::uint8_t rt, std::uint8_t rd, std::uint8_t shamt, std::uint8_t funct) { + this->dt = 0; + this->dt |= opcode << 26; + this->dt |= rs << 21; + this->dt |= rt << 16; + this->dt |= rd << 11; + this->dt |= shamt << 6; + this->dt |= funct; } -void Instruction::decode(Registers *regs) { - if (this->st != IS_FETCH) - // TODO other exception - throw std::exception(); - this->st = IS_DECODE; +Instruction::Instruction(std::uint8_t opcode, std::uint8_t rs, std::uint8_t rt, std::uint16_t immediate) { + this->dt = 0; + this->dt |= opcode << 26; + this->dt |= rs << 21; + this->dt |= rt << 16; + this->dt |= immediate; } -void Instruction::execute() { - if (this->st != IS_DECODE) - // TODO other exception - throw std::exception(); - this->st = IS_EXECUTE; +Instruction::Instruction(std::uint8_t opcode, std::uint32_t address) { + this->dt = 0; + this->dt |= opcode << 26; + this->dt |= address; } -void Instruction::memory(Memory *mem) { - if (this->st != IS_EXECUTE) - // TODO other exception - throw std::exception(); - this->st = IS_MEMORY; +QString Instruction::to_str() { + if (this->opcode() >= sizeof(instruction_map)) + return QString("UNKNOWN"); + return QString(instruction_map[this->opcode()].name); } -void Instruction::write_back(Registers *regs) { - if (this->st != IS_MEMORY) - // TODO other exception - throw std::exception(); - this->st = IS_WRITE_BACK; +#define MASK(LEN,OFF) ((this->dt >> (OFF)) & ((1 << (LEN)) - 1)) + +std::uint8_t Instruction::opcode() const { + return (std::uint8_t) MASK(6, 26); } -enum InstructionState Instruction::state() { - return this->st; +std::uint8_t Instruction::rs() const { + return (std::uint8_t) MASK(5, 21); } -bool Instruction::running() { - return this->st > IS_FETCH && this->st < IS_WRITE_BACK; +std::uint8_t Instruction::rt() const { + return (std::uint8_t) MASK(5, 16); } -bool Instruction::done() { - return this->st >= IS_WRITE_BACK; +std::uint8_t Instruction::rd() const { + return (std::uint8_t) MASK(5, 11); } -InstructionR::InstructionR(std::uint8_t rs, std::uint8_t rd, std::uint8_t rt, std::uint8_t sa) : Instruction() { - this->rs = rs; - this->rd = rd; - this->rt = rt; - this->sa = sa; +std::uint8_t Instruction::shamt() const { + return (std::uint8_t) MASK(5, 6); + } -// TODO for registers output as register ($0)! - -QVector<QString> InstructionR::to_strs() { - QVector<QString> str; - // Instruction name - str << "unknown"; // unknown instruction, should be replaced by child - // Source register - str << QString::number((unsigned)this->rs, 10); - // Target register - str << QString::number((unsigned)this->rt, 10); - // Destination register - str << QString::number((unsigned)this->rd, 10); - // Shift amount - str << QString::number((unsigned)this->sa, 10); - return str; +std::uint8_t Instruction::funct() const { + return (std::uint8_t) MASK(6, 0); } -InstructionI::InstructionI(std::uint8_t rs, std::uint8_t rt, std::uint16_t immediate) : Instruction() { - this->rs = rs; - this->rt = rt; - this->immediate = immediate; +std::uint16_t Instruction::immediate() const { + return (std::uint16_t) MASK(16, 0); } -QVector<QString> InstructionI::to_strs() { - QVector<QString> str; - // Instruction name - str << "unknown"; // unknown instruction, should be replaced by child - // Source register - str << QString::number((unsigned)this->rs, 10); - // Target register - str << QString::number((unsigned)this->rt, 10); - // Immediate value - str << QString::number((unsigned)this->immediate, 16); - return str; +std::uint32_t Instruction::address() const { + return (std::uint32_t) MASK(26, 0); } -InstructionJ::InstructionJ(std::uint32_t address) : Instruction() { - this->address = address; +std::uint32_t Instruction::data() const { + return this->dt; } -QVector<QString> InstructionJ::to_strs() { - QVector<QString> str; - // Instruction name - str << "unknown"; // unknown instruction, should be replaced by child - // Source register - str << QString::number((unsigned)this->address, 16); - return str; +bool Instruction::operator ==(const Instruction &c) const { + return (this->data() == c.data()); } |