aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzedarider <ymherklotz@gmail.com>2016-10-17 19:17:22 +0100
committerzedarider <ymherklotz@gmail.com>2016-10-17 19:17:22 +0100
commit6583a09d5f6bc673f7a664d47120f19827d2769c (patch)
treeda4c68e3c45dc2192bb2fa32fe1e5a49fbad7698
parentcea8c4ca10cd3a7453bc6311215dac4992fe7f52 (diff)
downloadMipsCPU-6583a09d5f6bc673f7a664d47120f19827d2769c.tar.gz
MipsCPU-6583a09d5f6bc673f7a664d47120f19827d2769c.zip
fully working add and sub
-rw-r--r--src/ymh15/mips_cpu.cpp47
-rw-r--r--src/ymh15/mips_cpu.obin13112 -> 13384 bytes
-rw-r--r--src/ymh15/mips_cpu_ymh15.hpp10
-rwxr-xr-xsrc/ymh15/test_mipsbin326912 -> 328152 bytes
-rw-r--r--src/ymh15/test_mips.cpp127
-rw-r--r--src/ymh15/test_mips.obin29616 -> 33176 bytes
-rw-r--r--src/ymh15/test_mips_ymh15.hpp4
7 files changed, 108 insertions, 80 deletions
diff --git a/src/ymh15/mips_cpu.cpp b/src/ymh15/mips_cpu.cpp
index 49e8cff..d3d4399 100644
--- a/src/ymh15/mips_cpu.cpp
+++ b/src/ymh15/mips_cpu.cpp
@@ -85,11 +85,11 @@ mips_error mips_cpu_step(mips_cpu_h state) {
return mips_ErrorInvalidArgument;
}
- read_instruction(state);
+ mips_error mips_err = read_instruction(state);
state->pc += 4;
- return mips_Success;
+ return mips_err;
}
mips_error mips_cpu_set_debug_level(mips_cpu_h state, unsigned level,
@@ -113,9 +113,7 @@ mips_error read_instruction(mips_cpu_h state) {
uint32_t inst;
mips_mem_read(state->mem, state->pc, 4, (uint8_t*)&inst);
- exec_instruction(state, inst);
-
- return mips_Success;
+ return exec_instruction(state, inst);
}
mips_error exec_instruction(mips_cpu_h state, uint32_t inst) {
@@ -132,45 +130,52 @@ mips_error exec_instruction(mips_cpu_h state, uint32_t inst) {
var[SHIFT] = (inst >> 6)&0x1f;
var[FUNC] = inst&0x3f;
- exec_R(state, var);
+ return exec_R(state, var);
} else if(((inst >> 26)&0x3f) < 4) {
var[OPCODE] = inst >> 26;
var[REG_S] = (inst >> 21)&0x1f;
var[REG_D] = (inst >> 16)&0x1f;
var[IMM] = inst&0xffff;
- exec_J(state, var);
+ return exec_J(state, var);
} else {
var[OPCODE] = inst >> 26;
var[MEM] = inst&0x3ffffff;
- exec_I(state, var);
+ return exec_I(state, var);
}
- return mips_Success;
+ return mips_ExceptionInvalidInstruction;
}
-void exec_R(mips_cpu_h state, uint32_t var[8]) {
+mips_error exec_R(mips_cpu_h state, uint32_t var[8]) {
if((var[FUNC]&0xf0) == 0x20 && (var[FUNC]&0xf) < 4) {
- add_sub(state, var);
+ return add_sub(state, var, ((int32_t)-(var[FUNC]&0xf)/2)*2+1);
}
+
+ return mips_Success;
}
-void exec_J(mips_cpu_h state, uint32_t var[8]) {
+mips_error exec_J(mips_cpu_h state, uint32_t var[8]) {
//TODO
+
+ return mips_Success;
}
-void exec_I(mips_cpu_h state, uint32_t var[8]) {
+mips_error exec_I(mips_cpu_h state, uint32_t var[8]) {
//TODO
+
+ return mips_Success;
}
-void add_sub(mips_cpu_h state, uint32_t var[8]) {
- if((var[FUNC]&0xf) < 2) {
- state->regs[var[REG_D]] = state->regs[var[REG_S]] +
- state->regs[var[REG_T]];
- state->overflow = 0;
- if((var[FUNC]&0xf) == 0) {
- state->overflow = 1;
- }
+mips_error add_sub(mips_cpu_h state, uint32_t var[8], int32_t add_sub) {
+ int32_t reg_s, reg_t, reg_d;
+ reg_s = (int32_t)state->regs[var[REG_S]];
+ reg_t = (int32_t)state->regs[var[REG_T]];
+ reg_d = reg_s + add_sub*reg_t;
+ if((var[FUNC]&0x1) == 1 || !((reg_s > 0 && add_sub*reg_t > 0 && reg_d < 0) || (reg_s < 0 && add_sub*reg_t < 0 && reg_d > 0))) {
+ state->regs[var[REG_D]] = (uint32_t)reg_d;
+ return mips_Success;
}
+ return mips_ExceptionArithmeticOverflow;
}
diff --git a/src/ymh15/mips_cpu.o b/src/ymh15/mips_cpu.o
index 403a250..c3067f3 100644
--- a/src/ymh15/mips_cpu.o
+++ b/src/ymh15/mips_cpu.o
Binary files differ
diff --git a/src/ymh15/mips_cpu_ymh15.hpp b/src/ymh15/mips_cpu_ymh15.hpp
index fea8c2f..5c6ea90 100644
--- a/src/ymh15/mips_cpu_ymh15.hpp
+++ b/src/ymh15/mips_cpu_ymh15.hpp
@@ -14,9 +14,11 @@
mips_error read_instruction(mips_cpu_h state);
mips_error exec_instruction(mips_cpu_h state, uint32_t inst);
-void exec_R(mips_cpu_h state, uint32_t var[8]);
-void exec_J(mips_cpu_h state, uint32_t var[8]);
-void exec_I(mips_cpu_h state, uint32_t var[8]);
-void add_sub(mips_cpu_h state, uint32_t var[8]);
+mips_error exec_R(mips_cpu_h state, uint32_t var[8]);
+mips_error exec_J(mips_cpu_h state, uint32_t var[8]);
+mips_error exec_I(mips_cpu_h state, uint32_t var[8]);
+mips_error add_sub(mips_cpu_h state, uint32_t var[8], int32_t add_sub);
+
+uint8_t get_msb(uint32_t word);
#endif // MIPS_CPU_YMH15_H
diff --git a/src/ymh15/test_mips b/src/ymh15/test_mips
index 40b7762..6d0340c 100755
--- a/src/ymh15/test_mips
+++ b/src/ymh15/test_mips
Binary files differ
diff --git a/src/ymh15/test_mips.cpp b/src/ymh15/test_mips.cpp
index 3523844..1b9ed42 100644
--- a/src/ymh15/test_mips.cpp
+++ b/src/ymh15/test_mips.cpp
@@ -8,32 +8,37 @@ using namespace std;
int main() {
mips_mem_h ram = mips_mem_create_ram(4096);
mips_cpu_h cpu = mips_cpu_create(ram);
-
- uint32_t inst = gen_instruction(9, 10, 8, 0, 0x21);
- uint32_t inst2 = gen_instruction(12, 13, 11, 0, 0x20);
- uint32_t ans;
- uint32_t ans2;
-
- mips_mem_write(ram, 0, 4, (uint8_t*)&inst);
- mips_mem_write(ram, 4, 4, (uint8_t*)&inst2);
- mips_cpu_set_register(cpu, 9, 4);
- mips_cpu_set_register(cpu, 10, 5);
- mips_cpu_set_register(cpu, 12, 232);
- mips_cpu_set_register(cpu, 13, 2356);
-
- mips_cpu_step(cpu);
- mips_cpu_step(cpu);
-
- mips_cpu_get_register(cpu, 8, &ans);
- mips_cpu_get_register(cpu, 11, &ans2);
+ srand(time(NULL));
+
+ mips_test_begin_suite();
+
+ int testId = mips_test_begin_test("ADD");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x20, 0x3fffffff, 0, 10), "Testing the adder without overflow");
+
+ testId = mips_test_begin_test("ADD");
+ mips_test_end_test(testId, !test_add(ram, cpu, 0x20, 0x7fffffff, 1, 1), "Testing the adder with overflow");
+
+ testId = mips_test_begin_test("ADDU");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x21, 0x3fffffff, 0, 10), "testing without overflow");
+
+ testId = mips_test_begin_test("ADDU");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x21, 0x7fffffff, 1, 1), "Testing the adder with overflow");
+
+ testId = mips_test_begin_test("SUB");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x22, 0x3fffffff, 0, 10), "Testing the adder without overflow");
+
+ testId = mips_test_begin_test("SUB");
+ mips_test_end_test(testId, !test_add(ram, cpu, 0x22, 0x7fffffff, 1, 1), "Testing the adder with overflow");
+
+ testId = mips_test_begin_test("SUBU");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x23, 0x3fffffff, 0, 10), "Testing the adder without overflow");
+
+ testId = mips_test_begin_test("SUBU");
+ mips_test_end_test(testId, test_add(ram, cpu, 0x23, 0x7fffffff, 1, 1), "Testing the adder with overflow");
+
- if(!ans || !ans2) {
- printf("failed\n");
- } else {
- printf("4 + 5 = %d\n", ans);
- printf("232 + 2356 = %d\n", ans2);
- }
+ mips_test_end_suite();
return 0;
}
@@ -62,40 +67,54 @@ uint32_t gen_instruction(uint32_t opcode, uint32_t memory) {
}
uint32_t change_endianness(uint32_t inst) {
- inst = (inst << 24 | ((inst << 8)&0x00ff0000) |
- ((inst >> 8)&0x0000ff00) |inst >> 24);
+ inst = (inst << 24 | ((inst << 8)&0xff0000) |
+ ((inst >> 8)&0xff00) |inst >> 24);
return inst;
}
-void test_endian(mips_mem_h ram) {
- uint32_t address, length, data, data0, data1, data2, data3, dataf;
- address = 0;
- length = 4;
- data = 0x01234567;
- data0 = 0;
- data1 = 0;
- data2 = 0;
- data3 = 0;
- dataf = 0;
-
- printf("Data in: %#010x\n", data);
-
- //data = (data << 24 | ((data << 8)&0x00ff0000) |
- // ((data >> 8)&0x0000ff00) |data >> 24);
-
- mips_mem_write(ram, address, length, (uint8_t*)&data);
- mips_mem_read(ram, address, 1, (uint8_t*)&data0);
- mips_mem_read(ram, address+1, 1, (uint8_t*)&data1);
- mips_mem_read(ram, address+2, 1, (uint8_t*)&data2);
- mips_mem_read(ram, address+3, 1, (uint8_t*)&data3);
-
- mips_mem_read(ram, address, 4, (uint8_t*)&dataf);
+int test_add(mips_mem_h ram, mips_cpu_h cpu, uint32_t type, uint32_t max, uint8_t value, unsigned i_t) {
+
+ uint32_t inst, ans, a, b;
+
+ for(unsigned i = 0; i < i_t; ++i) {
+ mips_error mips_err;
+ mips_cpu_reset(cpu);
+ inst = gen_instruction(9, 10, 8, 0, type);
+ if(value) {
+ a = max;
+ if(type > 0x21) {
+ b = -max;
+ } else {
+ b = max;
+ }
+ } else {
+ a = rand() % max;
+ b = rand() % max;
+ }
+
+ mips_mem_write(ram, 0, 4, (uint8_t*)&inst);
+
+ mips_cpu_set_register(cpu, 9, a);
+ mips_cpu_set_register(cpu, 10, b);
+
+ mips_err = mips_cpu_step(cpu);
- cout << "Data at " << address << ": " << data0 << endl;
- cout << "Data at " << address+1 << ": " << data1 << endl;
- cout << "Data at " << address+2 << ": " << data2 << endl;
- cout << "Data at " << address+3 << ": " << data3 << endl;
+ mips_cpu_get_register(cpu, 8, &ans);
+
+ if(type < 0x22) {
+ printf("%#10x + %#10x = %#10x\n", a, b, ans);
+ if(mips_err == mips_ExceptionArithmeticOverflow) {
+ return 0;
+ }
+ } else {
+ printf("%#10x - %#10x = %#10x\n", a, b, ans);
+ if(mips_err == mips_ExceptionArithmeticOverflow) {
+ return 0;
+ }
+ }
+
+ }
- printf("Dataf: %#010x\n", dataf);
+ return 1;
}
diff --git a/src/ymh15/test_mips.o b/src/ymh15/test_mips.o
index a095d53..6a13e71 100644
--- a/src/ymh15/test_mips.o
+++ b/src/ymh15/test_mips.o
Binary files differ
diff --git a/src/ymh15/test_mips_ymh15.hpp b/src/ymh15/test_mips_ymh15.hpp
index 98c9789..7b85ca4 100644
--- a/src/ymh15/test_mips_ymh15.hpp
+++ b/src/ymh15/test_mips_ymh15.hpp
@@ -2,6 +2,8 @@
#define TEST_MIPS_YMH15_H
#include "../../include/mips.h"
+#include <cstdlib>
+#include <ctime>
uint32_t gen_instruction(uint32_t src1, uint32_t src2, uint32_t dest,
uint32_t shift, uint32_t function);
@@ -10,6 +12,6 @@ uint32_t gen_instruction(uint32_t opcode, uint32_t src, uint32_t dest,
uint32_t gen_instruction(uint32_t opcode, uint32_t memory);
uint32_t change_endianness(uint32_t inst);
-void test_endian(mips_mem_h ram);
+int test_add(mips_mem_h ram, mips_cpu_h cpu, uint32_t type, uint32_t max, uint8_t value, unsigned i_t);
#endif // TEST_MIPS_YMH15_H