diff options
-rwxr-xr-x | makefile | 2 | ||||
-rw-r--r-- | src/shared/mips_mem_ram.o | bin | 0 -> 10000 bytes | |||
-rw-r--r-- | src/shared/mips_test_framework.o | bin | 0 -> 337728 bytes | |||
-rw-r--r-- | src/ymh15/mips_cpu.cpp | 181 | ||||
-rw-r--r-- | src/ymh15/mips_cpu.o | bin | 0 -> 13384 bytes | |||
-rw-r--r-- | src/ymh15/mips_cpu_ymh15.hpp | 24 | ||||
-rwxr-xr-x | src/ymh15/test_mips | bin | 0 -> 328152 bytes | |||
-rw-r--r-- | src/ymh15/test_mips.cpp | 120 | ||||
-rw-r--r-- | src/ymh15/test_mips.o | bin | 0 -> 33176 bytes | |||
-rw-r--r-- | src/ymh15/test_mips_ymh15.hpp | 17 |
10 files changed, 343 insertions, 1 deletions
@@ -1,6 +1,6 @@ # Your login. For example, mine is dt10. Yours # won't be eie2ugs... -LOGIN ?= eie2ugs +LOGIN ?= ymh15 # Turn on all warnings CPPFLAGS += -W -Wall diff --git a/src/shared/mips_mem_ram.o b/src/shared/mips_mem_ram.o Binary files differnew file mode 100644 index 0000000..718d8dc --- /dev/null +++ b/src/shared/mips_mem_ram.o diff --git a/src/shared/mips_test_framework.o b/src/shared/mips_test_framework.o Binary files differnew file mode 100644 index 0000000..9790ca3 --- /dev/null +++ b/src/shared/mips_test_framework.o diff --git a/src/ymh15/mips_cpu.cpp b/src/ymh15/mips_cpu.cpp new file mode 100644 index 0000000..d3d4399 --- /dev/null +++ b/src/ymh15/mips_cpu.cpp @@ -0,0 +1,181 @@ +#include "../../include/mips.h" +#include "mips_cpu_ymh15.hpp" + +struct mips_cpu_impl { + mips_mem_h mem; + uint32_t regs[32]; + uint32_t pc; + uint32_t overflow; +}; + +mips_cpu_h mips_cpu_create(mips_mem_h mem) { + mips_cpu_impl* new_mips_cpu = new mips_cpu_impl; + + new_mips_cpu->mem = mem; + new_mips_cpu->pc = 0; + new_mips_cpu->overflow = 0; + + for(int i = 0; i < 32; ++i) { + new_mips_cpu->regs[i] = 0; + } + + return new_mips_cpu; +} + +mips_error mips_cpu_reset(mips_cpu_h state) { + if(!state) { + return mips_ErrorInvalidArgument; + } + + state->pc = 0; + state->overflow = 0; + + for(int i = 0; i < 32; ++i) { + state->regs[i] = 0; + } + + return mips_Success; +} + +mips_error mips_cpu_get_register(mips_cpu_h state, unsigned index, + uint32_t *value) { + if(!state || !value) { + return mips_ErrorInvalidArgument; + } + + *value = state->regs[index]; + + return mips_Success; +} + +mips_error mips_cpu_set_register(mips_cpu_h state, unsigned index, + uint32_t value) { + if(!state) { + return mips_ErrorInvalidArgument; + } + + state->regs[index] = value; + + return mips_Success; +} + + +mips_error mips_cpu_set_pc(mips_cpu_h state, uint32_t pc) { + if(!state) { + return mips_ErrorInvalidArgument; + } + + state->pc = pc; + + return mips_Success; +} + +mips_error mips_cpu_get_pc(mips_cpu_h state, uint32_t *pc) { + if(!state || !pc) { + return mips_ErrorInvalidArgument; + } + + *pc = state->pc; + + return mips_Success; +} + +mips_error mips_cpu_step(mips_cpu_h state) { + if(!state) { + return mips_ErrorInvalidArgument; + } + + mips_error mips_err = read_instruction(state); + + state->pc += 4; + + return mips_err; +} + +mips_error mips_cpu_set_debug_level(mips_cpu_h state, unsigned level, + FILE *dest) { + if(!state || !dest) { + return mips_ErrorInvalidArgument; + } + + //TODO + + return mips_Success; +} + +void mips_cpu_free(mips_cpu_h state) { + if(state) { + delete state; + } +} + +mips_error read_instruction(mips_cpu_h state) { + uint32_t inst; + mips_mem_read(state->mem, state->pc, 4, (uint8_t*)&inst); + + return exec_instruction(state, inst); +} + +mips_error exec_instruction(mips_cpu_h state, uint32_t inst) { + uint32_t var[8]; + for(int i = 0; i < 8; ++i) { + var[i] = 0; + } + + if(((inst >> 26)&0x3f) == 0) { + // R Type + var[REG_S] = inst >> 21; + var[REG_T] = (inst >> 16)&0x1f; + var[REG_D] = (inst >> 11)&0x1f; + var[SHIFT] = (inst >> 6)&0x1f; + var[FUNC] = inst&0x3f; + + 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; + + return exec_J(state, var); + } else { + var[OPCODE] = inst >> 26; + var[MEM] = inst&0x3ffffff; + + return exec_I(state, var); + } + + return mips_ExceptionInvalidInstruction; +} + +mips_error exec_R(mips_cpu_h state, uint32_t var[8]) { + if((var[FUNC]&0xf0) == 0x20 && (var[FUNC]&0xf) < 4) { + return add_sub(state, var, ((int32_t)-(var[FUNC]&0xf)/2)*2+1); + } + + return mips_Success; +} + +mips_error exec_J(mips_cpu_h state, uint32_t var[8]) { + //TODO + + return mips_Success; +} + +mips_error exec_I(mips_cpu_h state, uint32_t var[8]) { + //TODO + + return mips_Success; +} + +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 Binary files differnew file mode 100644 index 0000000..c3067f3 --- /dev/null +++ b/src/ymh15/mips_cpu.o diff --git a/src/ymh15/mips_cpu_ymh15.hpp b/src/ymh15/mips_cpu_ymh15.hpp new file mode 100644 index 0000000..5c6ea90 --- /dev/null +++ b/src/ymh15/mips_cpu_ymh15.hpp @@ -0,0 +1,24 @@ +#ifndef MIPS_CPU_YMH15_H +#define MIPS_CPU_YMH15_H + +#include "../../include/mips.h" + +#define OPCODE 0 +#define REG_S 1 +#define REG_T 2 +#define REG_D 3 +#define SHIFT 4 +#define FUNC 5 +#define IMM 6 +#define MEM 7 + +mips_error read_instruction(mips_cpu_h state); +mips_error exec_instruction(mips_cpu_h state, uint32_t inst); +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 Binary files differnew file mode 100755 index 0000000..6d0340c --- /dev/null +++ b/src/ymh15/test_mips diff --git a/src/ymh15/test_mips.cpp b/src/ymh15/test_mips.cpp new file mode 100644 index 0000000..1b9ed42 --- /dev/null +++ b/src/ymh15/test_mips.cpp @@ -0,0 +1,120 @@ +#include "../../include/mips.h" +#include "test_mips_ymh15.hpp" + +#include <iostream> + +using namespace std; + +int main() { + mips_mem_h ram = mips_mem_create_ram(4096); + mips_cpu_h cpu = mips_cpu_create(ram); + + 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"); + + + mips_test_end_suite(); + return 0; +} + +// R Type +uint32_t gen_instruction(uint32_t src1, uint32_t src2, uint32_t dest, + uint32_t shift, uint32_t function) { + uint32_t inst = 0; + inst = inst | src1 << 21 | src2 << 16 | dest << 11 | shift << 6 | + function; + return inst; +} + +// I Type +uint32_t gen_instruction(uint32_t opcode, uint32_t src, uint32_t dest, + uint32_t Astart) { + uint32_t inst = 0; + inst = inst | opcode << 26 | src << 21 | dest << 16 | Astart; + return inst; +} + +// J Type +uint32_t gen_instruction(uint32_t opcode, uint32_t memory) { + uint32_t inst = 0; + inst = inst | opcode << 26 | memory; + return inst; +} + +uint32_t change_endianness(uint32_t inst) { + inst = (inst << 24 | ((inst << 8)&0xff0000) | + ((inst >> 8)&0xff00) |inst >> 24); + return inst; +} + +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); + + 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; + } + } + + } + + return 1; +} + diff --git a/src/ymh15/test_mips.o b/src/ymh15/test_mips.o Binary files differnew file mode 100644 index 0000000..6a13e71 --- /dev/null +++ b/src/ymh15/test_mips.o diff --git a/src/ymh15/test_mips_ymh15.hpp b/src/ymh15/test_mips_ymh15.hpp new file mode 100644 index 0000000..7b85ca4 --- /dev/null +++ b/src/ymh15/test_mips_ymh15.hpp @@ -0,0 +1,17 @@ +#ifndef TEST_MIPS_YMH15_H +#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); +uint32_t gen_instruction(uint32_t opcode, uint32_t src, uint32_t dest, + uint32_t Astart); +uint32_t gen_instruction(uint32_t opcode, uint32_t memory); +uint32_t change_endianness(uint32_t inst); + +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 |