aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--instructions.md27
-rw-r--r--qtmips_machine/alu.cpp8
-rw-r--r--qtmips_machine/instruction.cpp6
-rw-r--r--qtmips_machine/instruction.h3
-rw-r--r--qtmips_machine/tests/testcore.cpp70
5 files changed, 92 insertions, 22 deletions
diff --git a/instructions.md b/instructions.md
index bbeac20..a3ee0a0 100644
--- a/instructions.md
+++ b/instructions.md
@@ -4,6 +4,7 @@ This is list of all MIPS1 instructions and their implementation status in QtMips
Explanation of checkboxes:
* [ ] Not tested
+* [?] Somewhat tested but not sure about correctness of implementation
* [-] Tested non-pipelined core
* [x] Tested on non-pipelined and pipelined core
@@ -12,7 +13,7 @@ CPU Arithmetic Instruction
* [-] ADD
* [ ] ADDI
* [ ] ADDIU
-* [ ] ADDU
+* [-] ADDU
* [ ] CLO
* [ ] CLZ
* [ ] DIV
@@ -24,12 +25,12 @@ CPU Arithmetic Instruction
* [ ] MUL
* [ ] MULT
* [ ] MULTU
-* [ ] SLT
+* [-] SLT
* [ ] SLTI
* [ ] SLTIU
-* [ ] SLTU
-* [ ] SUB
-* [ ] SUBU
+* [?] SLTU
+* [-] SUB
+* [-] SUBU
CPU Branch and Jump Instructions
--------------------------------
@@ -48,8 +49,8 @@ CPU Branch and Jump Instructions
* [ ] JALR
* [ ] JR
-CPU Instruction Control Instruction
------------------------------------
+CPU No Instructions
+-------------------
* [ ] NOP
* [ ] SSNOP
@@ -96,12 +97,12 @@ CPU Move Instruction
CPU Shift Instructions
----------------------
-* [ ] SLL
-* [ ] SLLV
-* [ ] SRA
-* [ ] SRAV
-* [ ] SRL
-* [ ] SRLV
+* [-] SLL
+* [-] SLLV
+* [?] SRA
+* [?] SRAV
+* [-] SRL
+* [-] SRLV
CPU Trap Instructions
---------------------
diff --git a/qtmips_machine/alu.cpp b/qtmips_machine/alu.cpp
index 85bc804..912ccf5 100644
--- a/qtmips_machine/alu.cpp
+++ b/qtmips_machine/alu.cpp
@@ -8,15 +8,15 @@ std::uint32_t alu_operate(enum AluOp operation, std::uint32_t s, std::uint32_t t
case ALU_OP_SRL:
return t >> sa;
case ALU_OP_SRA:
- // TODO is this correct implementation? (Shouldn't we be masking top most bit?)
- return (t >> sa) | (t & 0x80000000);
+ // TODO is this correct implementation? (Should we be masking top most bit?)
+ return ((t & 0x7fffffff) >> sa) | (t & 0x80000000);
case ALU_OP_SLLV:
return t << s;
case ALU_OP_SRLV:
return t >> s;
case ALU_OP_SRAV:
- // TODO is this correct implementation? (Shouldn't we be masking top most bit?)
- return (t >> s) | (t & 0x80000000);
+ // TODO is this correct implementation? (Should we be masking top most bit?)
+ return ((t & 0x7fffffff) >> s) | (t & 0x80000000);
case ALU_OP_ADD:
if (s > (0xFFFFFFFF - t))
throw QTMIPS_EXCEPTION(Overflow, "ADD operation overflow/underflow", QString::number(s) + QString(" + ") + QString::number(t));
diff --git a/qtmips_machine/instruction.cpp b/qtmips_machine/instruction.cpp
index 91bd1c8..58b6ffa 100644
--- a/qtmips_machine/instruction.cpp
+++ b/qtmips_machine/instruction.cpp
@@ -109,6 +109,10 @@ std::uint32_t Instruction::data() const {
return this->dt;
}
-bool Instruction::operator ==(const Instruction &c) const {
+bool Instruction::operator==(const Instruction &c) const {
return (this->data() == c.data());
}
+
+bool Instruction::operator!=(const Instruction &c) const {
+ return ! this->operator==(c);
+}
diff --git a/qtmips_machine/instruction.h b/qtmips_machine/instruction.h
index 921d9b0..aa53973 100644
--- a/qtmips_machine/instruction.h
+++ b/qtmips_machine/instruction.h
@@ -26,7 +26,8 @@ public:
std::uint32_t address() const;
std::uint32_t data() const;
- bool operator ==(const Instruction &c) const;
+ bool operator==(const Instruction &c) const;
+ bool operator!=(const Instruction &c) const;
private:
std::uint32_t dt;
diff --git a/qtmips_machine/tests/testcore.cpp b/qtmips_machine/tests/testcore.cpp
index 5320a6b..f4a3e4b 100644
--- a/qtmips_machine/tests/testcore.cpp
+++ b/qtmips_machine/tests/testcore.cpp
@@ -7,20 +7,83 @@ void MachineTests::core_regs_data() {
QTest::addColumn<Registers>("res");
// Note that we shouldn't be touching program counter as that is handled automatically and differs if we use pipelining
- // Test arithmetic instructions
+ // Arithmetic instructions
{
Registers regs_init;
- regs_init.write_gp(24, 12);
- regs_init.write_gp(25, 24);
+ regs_init.write_gp(24, 24);
+ regs_init.write_gp(25, 12);
Registers regs_res(regs_init);
regs_res.write_gp(26, 36);
QTest::newRow("ADD") << Instruction(0, 24, 25, 26, 0, 32) \
<< regs_init \
<< regs_res;
+ QTest::newRow("ADDU") << Instruction(0, 24, 25, 26, 0, 33) \
+ << regs_init \
+ << regs_res;
+ regs_res.write_gp(26, 12);
+ QTest::newRow("SUB") << Instruction(0, 24, 25, 26, 0, 34) \
+ << regs_init \
+ << regs_res;
+ QTest::newRow("SUBU") << Instruction(0, 24, 25, 26, 0, 35) \
+ << regs_init \
+ << regs_res;
+ }
+ {
+ Registers regs_init;
+ regs_init.write_gp(24, 12);
+ regs_init.write_gp(25, 24);
+ Registers regs_res(regs_init);
+ regs_res.write_gp(26, 1);
+ QTest::newRow("SLT") << Instruction(0, 24, 25, 26, 0, 42) \
+ << regs_init \
+ << regs_res;
+ QTest::newRow("SLTU") << Instruction(0, 24, 25, 26, 0, 43) \
+ << regs_init \
+ << regs_res;
+ }
+
+ // Shift instructions
+ {
+ Registers regs_init;
+ regs_init.write_gp(24, 0xf0);
+ regs_init.write_gp(25, 3);
+ Registers regs_res(regs_init);
+ regs_res.write_gp(26, 0x780);
+ QTest::newRow("SLL") << Instruction(0, 0, 24, 26, 3, 0) \
+ << regs_init \
+ << regs_res;
+ QTest::newRow("SLLV") << Instruction(0, 25, 24, 26, 0, 4) \
+ << regs_init \
+ << regs_res;
+ regs_res.write_gp(26, 0x1e);
+ QTest::newRow("SLR") << Instruction(0, 0, 24, 26, 3, 2) \
+ << regs_init \
+ << regs_res;
+ QTest::newRow("SLRV") << Instruction(0, 25, 24, 26, 0, 6) \
+ << regs_init \
+ << regs_res;
+ }
+ {
+ Registers regs_init;
+ regs_init.write_gp(24, 0x800000f0);
+ regs_init.write_gp(25, 3);
+ Registers regs_res(regs_init);
+ regs_res.write_gp(26, 0x8000001e);
+ QTest::newRow("SRA") << Instruction(0, 0, 24, 26, 3, 3) \
+ << regs_init \
+ << regs_res;
+ QTest::newRow("SRAV") << Instruction(0, 25, 24, 26, 0, 7) \
+ << regs_init \
+ << regs_res;
}
// TODO test other operations
}
+/*
+#include <iostream>
+using namespace std;
+*/
+
void MachineTests::core_regs() {
QFETCH(Instruction, i);
QFETCH(Registers, init);
@@ -35,6 +98,7 @@ void MachineTests::core_regs() {
Registers regs_single(init); // Create registers copy
CoreSingle core_single(&regs_single, &mem_single);
core_single.step(); // Single step should be enought as this is risc without pipeline
+ //cout << "well:" << hex << regs_single.read_gp(26) << endl;
QCOMPARE(regs_single, res); // After doing changes from initial state this should be same state as in case of passed expected result
QCOMPARE(mem, mem_single); // There should be no change in memory