From 6583a09d5f6bc673f7a664d47120f19827d2769c Mon Sep 17 00:00:00 2001 From: zedarider Date: Mon, 17 Oct 2016 19:17:22 +0100 Subject: fully working add and sub --- src/ymh15/mips_cpu.cpp | 47 +++++++++------- src/ymh15/mips_cpu.o | Bin 13112 -> 13384 bytes src/ymh15/mips_cpu_ymh15.hpp | 10 ++-- src/ymh15/test_mips | Bin 326912 -> 328152 bytes src/ymh15/test_mips.cpp | 127 ++++++++++++++++++++++++------------------ src/ymh15/test_mips.o | Bin 29616 -> 33176 bytes src/ymh15/test_mips_ymh15.hpp | 4 +- 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 Binary files a/src/ymh15/mips_cpu.o and b/src/ymh15/mips_cpu.o 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 Binary files a/src/ymh15/test_mips and b/src/ymh15/test_mips 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 Binary files a/src/ymh15/test_mips.o and b/src/ymh15/test_mips.o 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 +#include 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 -- cgit