aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzedarider <ymherklotz@gmail.com>2016-10-27 13:54:04 +0100
committerzedarider <ymherklotz@gmail.com>2016-10-27 13:54:04 +0100
commita09d256996261c481fd7fab1bd11865a2144bbd7 (patch)
tree34dc5393808c415222c10c4f28a06a14fb1a3ed0
parent5b5ae1e32eef63ca9990fb80134851b402d51906 (diff)
downloadMipsCPU-a09d256996261c481fd7fab1bd11865a2144bbd7.tar.gz
MipsCPU-a09d256996261c481fd7fab1bd11865a2144bbd7.zip
nearly finished
l---------src/ymh15/.#mips_cpu.cpp1
-rw-r--r--src/ymh15/mips_cpu.cpp207
-rw-r--r--src/ymh15/mips_cpu.obin21024 -> 25904 bytes
-rw-r--r--src/ymh15/mips_cpu_ymh15.hpp67
-rwxr-xr-xsrc/ymh15/test_mipsbin335808 -> 341840 bytes
-rw-r--r--src/ymh15/test_mips.cpp141
-rw-r--r--src/ymh15/test_mips.obin40168 -> 46200 bytes
-rw-r--r--src/ymh15/test_mips_ymh15.hpp33
8 files changed, 412 insertions, 37 deletions
diff --git a/src/ymh15/.#mips_cpu.cpp b/src/ymh15/.#mips_cpu.cpp
new file mode 120000
index 0000000..5a5142f
--- /dev/null
+++ b/src/ymh15/.#mips_cpu.cpp
@@ -0,0 +1 @@
+yannherklotz@Yann-Arch.800:1477569971 \ No newline at end of file
diff --git a/src/ymh15/mips_cpu.cpp b/src/ymh15/mips_cpu.cpp
index 02ca75a..34107de 100644
--- a/src/ymh15/mips_cpu.cpp
+++ b/src/ymh15/mips_cpu.cpp
@@ -27,6 +27,8 @@ mips_cpu_h mips_cpu_create(mips_mem_h mem) {
state->pc = 0;
state->next_pc = state->pc + 4;
state->delay_slot = 0;
+ state->lo = 0;
+ state->hi = 0;
state->debug_level = 0;
state->debug_type = NULL;
@@ -48,6 +50,8 @@ mips_error mips_cpu_reset(mips_cpu_h state) {
state->pc = 0;
state->next_pc = state->pc + 4;
state->delay_slot = 0;
+ state->hi = 0;
+ state->lo = 0;
// and registers
for(int i = 0; i < 32; ++i) {
@@ -59,7 +63,7 @@ mips_error mips_cpu_reset(mips_cpu_h state) {
mips_error mips_cpu_get_register(mips_cpu_h state, unsigned index,
uint32_t *value) {
- if(!state || !value || index > 31) {
+ if(!state || !value || index > 31 || index == 0) {
return mips_ErrorInvalidArgument;
}
@@ -71,7 +75,7 @@ mips_error mips_cpu_get_register(mips_cpu_h state, unsigned index,
mips_error mips_cpu_set_register(mips_cpu_h state, unsigned index,
uint32_t value) {
- if(!state || index > 31) {
+ if(!state || index > 31 || index == 0) {
return mips_ErrorInvalidArgument;
}
@@ -234,9 +238,19 @@ mips_error exec_R(mips_cpu_h state, uint32_t var[8]) {
} else if(var[FUNC] == 8) {
// jr
return jump(state, var, 0);
+
} else if(var[FUNC] == 9) {
// jalr
return jump(state, var, 1);
+
+ } else if(var[FUNC] >= 0x10 && var[FUNC] <= 0x13) {
+ // mfhi mthi mflo mtlo
+ return move(state, var);
+
+ } else if(var[FUNC] >= 0x18 && var[FUNC] <= 0x1b) {
+ // mult multu div divu
+ return mult_div(state, var);
+
} else {
// otherwise return that it was an invalid instruction
return mips_ExceptionInvalidInstruction;
@@ -257,30 +271,48 @@ mips_error exec_J(mips_cpu_h state, uint32_t var[8]) {
mips_error exec_I(mips_cpu_h state, uint32_t var[8]) {
switch(var[OPCODE]) {
- case 1: // bgez, bgezal, bltz, bltzal
+ case 0x1: // bgez, bgezal, bltz, bltzal
return branch(state, var);
- case 4: // beq
+ case 0x4: // beq
return branch(state, var);
- case 5: // bne
+ case 0x5: // bne
return branch(state, var);
- case 6: // blez
+ case 0x6: // blez
return branch(state, var);
- case 7: // bgtz
+ case 0x7: // bgtz
return branch(state, var);
- case 8: // addi
+ case 0x8: // addi
return add_sub(state, var, 1, 1);
- case 9: // addiu
+ case 0x9: // addiu
return add_sub(state, var, 1, 2);
- case 12: // andi
+ case 0xc: // andi
return bitwise(state, var, 1);
- case 13: // ori
+ case 0xd: // ori
return bitwise(state, var, 1);
- case 14: // xori
+ case 0xe: // xori
return bitwise(state, var, 1);
- case 32: // lb
+ case 0xf: // lui
+ return load(state, var);
+ case 0x20: // lb
+ return load(state, var);
+ case 0x21: // lh
+ return load(state, var);
+ case 0x22: // lwl
+ return load(state, var);
+ case 0x23: // lw
return load(state, var);
- case 36: // lbu
+ case 0x24: // lbu
return load(state, var);
+ case 0x25: // lhu
+ return load(state, var);
+ case 0x26: // lwr
+ return load(state, var);
+ case 0x28: // sb
+ return store(state, var);
+ case 0x29: // sh
+ return store(state, var);
+ case 0x2b: // sw
+ return store(state, var);
default:
return mips_ExceptionInvalidInstruction;
}
@@ -361,7 +393,7 @@ mips_error jump(mips_cpu_h state, uint32_t var[8], uint8_t link) {
jump_loc = state->regs[var[REG_S]];
reg_d = var[REG_D];
} else {
- jump_loc = var[IMM]<<2;
+ jump_loc = var[MEM]<<2;
reg_d = 31;
}
@@ -378,22 +410,157 @@ mips_error jump(mips_cpu_h state, uint32_t var[8], uint8_t link) {
mips_error load(mips_cpu_h state, uint32_t var[8]) {
uint32_t addr;
uint8_t mem_byte;
+ uint16_t mem_halfword;
+ uint32_t mem_word;
addr = state->regs[var[REG_S]] + var[IMM];
- mips_mem_read(state->mem, addr, 1, &mem_byte);
+ if(var[OPCODE] == 0x24 || var[OPCODE] == 0x20) { // lb lbu
+ mips_mem_read(state->mem, addr, 1, &mem_byte);
+ } else if(var[OPCODE] == 0x21 || var[OPCODE] == 0x25) { // lh lhu
+ if((addr&0b1) == 1) {
+ return mips_ExceptionInvalidAddress;
+ }
+ mips_mem_read(state->mem, addr, 2, (uint8_t*)&mem_halfword);
+ mem_halfword = mem_halfword>>8 | mem_halfword<<8;
+ } else if(var[OPCODE] == 0x23 || var[OPCODE] == 0x22) { // lw lwl
+ if((addr&0b1) == 1 || (addr&0b10)>>1 == 1) {
+ return mips_ExceptionInvalidAddress;
+ }
+ mips_mem_read(state->mem, addr, 4, (uint8_t*)&mem_word);
+ mem_word = (mem_word<<24) | ((mem_word>>8)&0xff00) | ((mem_word<<8)&0xff0000) | (mem_word>>24);
+ } else if(var[OPCODE] == 0x26) { // lwr
+ if((addr&0b1) == 0 || (addr&0b10)>>1 == 0) {
+ return mips_ExceptionInvalidAddress;
+ }
+ mips_mem_read(state->mem, addr-3, 4, (uint8_t*)&mem_word);
+ mem_word = (mem_word<<24) | ((mem_word>>8)&0xff00) | ((mem_word<<8)&0xff0000) | (mem_word>>24);
+ }
- if(var[OPCODE] == 0x24) {
- state->regs[var[REG_D]] = (uint32_t)mem_byte;
- } else if(var[OPCODE] == 0x20){
+ switch(var[OPCODE]) {
+ case 0xf:
+ state->regs[var[REG_D]] = var[IMM]<<16;
+ return mips_Success;
+ case 0x20:
state->regs[var[REG_D]] = (uint32_t)(int8_t)mem_byte;
+ return mips_Success;
+ case 0x21:
+ state->regs[var[REG_D]] = (uint32_t)(int16_t)mem_halfword;
+ return mips_Success;
+ case 0x22:
+ state->regs[var[REG_D]] = (mem_word&0xffff0000)|(state->regs[var[REG_D]]&0xffff);
+ return mips_Success;
+ case 0x23:
+ state->regs[var[REG_D]] = mem_word;
+ return mips_Success;
+ case 0x24:
+ state->regs[var[REG_D]] = (uint32_t)mem_byte;
+ return mips_Success;
+ case 0x25:
+ state->regs[var[REG_D]] = (uint32_t)mem_halfword;
+ return mips_Success;
+ case 0x26:
+ state->regs[var[REG_D]] = (state->regs[var[REG_D]]&0xffff0000)|(mem_word&0xffff);
+ return mips_Success;
+ default:
+ return mips_ExceptionInvalidInstruction;
+ }
+}
+
+mips_error store(mips_cpu_h state, uint32_t var[8]) {
+ uint32_t addr;
+ uint32_t word;
+ uint16_t half_word;
+ uint8_t byte;
+
+ addr = state->regs[var[REG_S]] + var[IMM];
+ word = state->regs[var[REG_D]];
+ half_word = (uint16_t)state->regs[var[REG_D]];
+ byte = (uint8_t)state->regs[var[REG_D]];
+
+ if(var[OPCODE] == 0x28) {
+ mips_mem_write(state->mem, addr, 1, &byte);
+ } else if(var[OPCODE] == 0x29) {
+ if((addr&0b1) == 1) {
+ return mips_ExceptionInvalidAddress;
+ }
+ uint16_t tmp = half_word << 8 | half_word >> 8;
+ mips_mem_write(state->mem, addr, 2, (uint8_t*)&tmp);
+ } else if(var[OPCODE] == 0x2b) {
+ if((addr&0b1) == 1 || (addr&0b10)>>1 == 1) {
+ return mips_ExceptionInvalidAddress;
+ }
+ uint32_t tmp = word<<24 | ((word>>8)&0xff00) | ((word<<8)&0xff0000) | word>>24;
+ mips_mem_write(state->mem, addr, 4, (uint8_t*)&tmp);
} else {
return mips_ExceptionInvalidInstruction;
}
+ return mips_Success;
+}
+mips_error move(mips_cpu_h state, uint32_t var[8]) {
+ switch(var[FUNC]) {
+ case 0x10:
+ return mips_cpu_set_register(state, var[REG_D], state->hi);
+ case 0x11:
+ return mips_cpu_get_register(state, var[REG_D], &state->hi);
+ case 0x12:
+ return mips_cpu_set_register(state, var[REG_D], state->lo);
+ case 0x13:
+ return mips_cpu_get_register(state, var[REG_D], &state->lo);
+ default:
+ return mips_ExceptionInvalidInstruction;
+ }
return mips_Success;
}
-mips_error store(mips_cpu_h state, uint32_t var[8]) {
+mips_error mult_div(mips_cpu_h state, uint32_t var[8]) {
+ uint64_t unsigned_result, signed_result;
+ switch(var[FUNC]) {
+ case 0x18: // mult
+ signed_result = ((int64_t)(int32_t)state->regs[var[REG_S]])*((int64_t)(int32_t)state->regs[var[REG_T]]);
+ state->lo = (uint32_t)signed_result;
+ state->hi = (uint32_t)(signed_result>>32);
+ return mips_Success;
+
+ case 0x19: // multu
+ unsigned_result = ((uint64_t)state->regs[var[REG_S]])*((uint64_t)state->regs[var[REG_T]]);
+ state->lo = (uint32_t)unsigned_result;
+ state->hi = (uint32_t)(unsigned_result>>32);
+ return mips_Success;
+
+ case 0x1a: // div
+ if(var[REG_T] == 0) {
+ state->lo = 0;
+ state->hi = 0;
+ return mips_Success;
+ }
+
+ state->lo = ((int32_t)state->regs[var[REG_S]])/((int32_t)state->regs[var[REG_T]]);
+ state->hi = ((int32_t)state->regs[var[REG_S]])%((int32_t)state->regs[var[REG_T]]);
+ return mips_Success;
+
+ case 0x1b: // divu
+ if(var[REG_T] == 0) {
+ state->lo = 0;
+ state->hi = 0;
+ return mips_Success;
+ }
+
+ state->lo = (state->regs[var[REG_S]])/(state->regs[var[REG_T]]);
+ state->hi = (state->regs[var[REG_S]])%(state->regs[var[REG_T]]);
+ return mips_Success;
+
+ default:
+ return mips_ExceptionInvalidInstruction;
+ }
+}
+
+mips_error shift(mips_cpu_h state, uint32_t var[8]) {
+ if(var[FUNC] == 0 && var[OPCODE] == 0) {
+ state->regs[var[REG_D]] = state->regs[var[REG_T]] << var[SHIFT];
+ } else if(var[FUNC] == 4) {
+ state->regs[var[REG_D]] = state->regs[var[REG_T]] << state->regs[var[REG_S]];
+ } else if(var[FUNC] == 2/*TODO*/);
return mips_Success;
}
diff --git a/src/ymh15/mips_cpu.o b/src/ymh15/mips_cpu.o
index 1422c47..4092c0a 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 2a95db1..085c59c 100644
--- a/src/ymh15/mips_cpu_ymh15.hpp
+++ b/src/ymh15/mips_cpu_ymh15.hpp
@@ -15,24 +15,79 @@
#define IMM 6
#define MEM 7
+// Functions
+#define SLL 0x0
+#define SRL 0x2
+#define SRA 0x3
+#define SLLV 0x4
+#define SRLV 0x6
+#define SRAV 0x7
+#define JR 0x8
+#define JALR 0x9
+#define MFHI 0x10
+#define MTHI 0x11
+#define MFLO 0x12
+#define MTLO 0x13
+#define MULT 0x18
+#define MULTU 0x19
+#define DIV 0x1a
+#define DIVU 0x1b
+#define ADD 0x20
+#define ADDU 0x21
+#define SUB 0x22
+#define SUBU 0x23
+#define AND 0x24
+#define OR 0x25
+#define XOR 0x26
+#define SLT 0x2a
+#define SLTU 0x2b
+
+// OPcodes
+#define BGEZ 0x1
+#define BGEZAL 0x1
+#define BLTZ 0x1
+#define BLTZAL 0x1
+#define J 0x2
+#define JAL 0x3
+#define BEQ 0x4
+#define BNE 0x5
+#define BLEZ 0x6
+#define BGTZ 0x7
+#define ADDI 0x8
+#define ADDIU 0x9
+#define SLTI 0xa
+#define SLTIU 0xb
+#define ANDI 0xc
+#define ORI 0xd
+#define XORI 0xe
+#define LUI 0xf
+#define LB 0x20
+#define LH 0x21
+#define LWL 0x22
+#define LW 0x23
+#define LBU 0x24
+#define LHU 0x25
+#define LWR 0x26
+#define SB 0x28
+#define SH 0x29
+#define SW 0x2b
+
// executes an instruction by first decoding it and sending the right
// variables to the different functions to be correctly interpreted
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]);
-
// performs addition and subtraction
-mips_error add_sub(mips_cpu_h state, uint32_t var[8], int32_t add_sub,
- int32_t imm);
+mips_error add_sub(mips_cpu_h state, uint32_t var[8], int32_t add_sub,int32_t imm);
// performs bitwise operations
mips_error bitwise(mips_cpu_h state, uint32_t var[8], unsigned imm);
-
mips_error branch(mips_cpu_h state, uint32_t var[8]);
-
mips_error jump(mips_cpu_h state, uint32_t var[8], uint8_t link);
-
mips_error load(mips_cpu_h state, uint32_t var[8]);
mips_error store(mips_cpu_h state, uint32_t var[8]);
+mips_error move(mips_cpu_h state, uint32_t var[8]);
+mips_error mult_div(mips_cpu_h state, uint32_t var[8]);
+mips_error shift(mips_cpu_h state, uint32_t var[8]);
#endif // MIPS_CPU_YMH15_H
diff --git a/src/ymh15/test_mips b/src/ymh15/test_mips
index ba7ccb4..3c01c18 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 5078b45..75afaa8 100644
--- a/src/ymh15/test_mips.cpp
+++ b/src/ymh15/test_mips.cpp
@@ -92,22 +92,52 @@ int main(int argc, char** argv) {
mips_test_end_test(testId, test_branch(ram, cpu, 1, -1, 0, 16, 20), "Testing BGEZ");
testId = mips_test_begin_test("J");
- mips_test_end_test(testId, test_branch(ram, cpu, 1, -1, 0, 16, 20), "Testing BGEZ");
+ mips_test_end_test(testId, test_jump(ram, cpu, J), "Testing J");
testId = mips_test_begin_test("JAL");
- mips_test_end_test(testId, test_branch(ram, cpu, 1, -1, 0, 16, 20), "Testing BGEZ");
+ mips_test_end_test(testId, test_jump(ram, cpu, JAL), "Testing JAL");
testId = mips_test_begin_test("JALR");
- mips_test_end_test(testId, test_branch(ram, cpu, 1, -1, 0, 16, 20), "Testing BGEZ");
+ mips_test_end_test(testId, test_jump(ram, cpu, JALR), "Testing JALR");
testId = mips_test_begin_test("JR");
- mips_test_end_test(testId, test_branch(ram, cpu, 1, -1, 0, 16, 20), "Testing BGEZ");
+ mips_test_end_test(testId, test_jump(ram, cpu, JR), "Testing JR");
testId = mips_test_begin_test("LB");
- mips_test_end_test(testId, test_load(ram, cpu, LB, 0xff), "Testing LB");
+ mips_test_end_test(testId, test_load(ram, cpu, LB, 0xf7), "Testing LB");
testId = mips_test_begin_test("LBU");
- mips_test_end_test(testId, test_load(ram, cpu, LBU, 0xff), "Testing LB");
+ mips_test_end_test(testId, test_load(ram, cpu, LBU, 0xf7), "Testing LBU");
+
+ testId = mips_test_begin_test("LH");
+ mips_test_end_test(testId, test_load(ram, cpu, LH, 0xff7f), "Testing LH");
+
+ testId = mips_test_begin_test("LHU");
+ mips_test_end_test(testId, test_load(ram, cpu, LHU, 0xff7f), "Testing LHU");
+
+ testId = mips_test_begin_test("LW");
+ mips_test_end_test(testId, test_load(ram, cpu, LW, 0xffffff7f), "Testing LW");
+
+ testId = mips_test_begin_test("LUI");
+ mips_test_end_test(testId, test_load(ram, cpu, LUI, 0xff7f), "Testing LUI");
+
+ testId = mips_test_begin_test("LWL");
+ mips_test_end_test(testId, test_load(ram, cpu, LWL, 0xff6fff7f), "Testing LWL");
+
+ testId = mips_test_begin_test("LWR");
+ mips_test_end_test(testId, test_load(ram, cpu, LWR, 0xff6fff7f), "Testing LWR");
+
+ testId = mips_test_begin_test("MULT");
+ mips_test_end_test(testId, test_mult_div(ram, cpu, MULT, 5, -4), "Testing LWR");
+
+ testId = mips_test_begin_test("MULTU");
+ mips_test_end_test(testId, test_mult_div(ram, cpu, MULTU, 5, -4), "Testing LWR");
+
+ testId = mips_test_begin_test("DIV");
+ mips_test_end_test(testId, test_mult_div(ram, cpu, DIV, 5, -4), "Testing LWR");
+
+ testId = mips_test_begin_test("DIVU");
+ mips_test_end_test(testId, test_mult_div(ram, cpu, DIVU, 5, -4), "Testing LWR");
mips_test_end_suite();
return 0;
@@ -324,38 +354,129 @@ int test_branch(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t a, uin
int test_jump(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode) {
int passed = 0;
- uint32_t inst;
+ uint32_t inst, reg10, reg13, reg16, reg31;
mips_cpu_reset(cpu);
if(opcode == 2 || opcode == 3) {
inst = change_endianness(gen_instruction(opcode, 0x20));
+ } else if(opcode == 8 || opcode == 9) {
+ inst = change_endianness(gen_instruction(25, 0, 31, 0, opcode));
+ }
+
+ mips_mem_write(ram, 0, 4, (uint8_t*)&inst);
+
+ inst = change_endianness(gen_instruction(8, 9, 10, 0, ADDU));
+ mips_mem_write(ram, 4, 4, (uint8_t*)&inst);
+ inst = change_endianness(gen_instruction(11, 12, 13, 0, ADDU));
+ mips_mem_write(ram, 8, 4, (uint8_t*)&inst);
+ inst = change_endianness(gen_instruction(14, 15, 16, 0, ADDU));
+ mips_mem_write(ram, 0x20<<2, 4, (uint8_t*)&inst);
+
+ mips_cpu_set_register(cpu, 8, 8);
+ mips_cpu_set_register(cpu, 9, 9);
+ mips_cpu_set_register(cpu, 10, 10);
+ mips_cpu_set_register(cpu, 11, 11);
+ mips_cpu_set_register(cpu, 12, 12);
+ mips_cpu_set_register(cpu, 13, 13);
+ mips_cpu_set_register(cpu, 14, 14);
+ mips_cpu_set_register(cpu, 15, 15);
+ mips_cpu_set_register(cpu, 16, 16);
+ mips_cpu_set_register(cpu, 25, 0x20<<2);
+
+ mips_cpu_step(cpu);
+ mips_cpu_step(cpu);
+ mips_cpu_step(cpu);
+
+ mips_cpu_get_register(cpu, 10, &reg10);
+ mips_cpu_get_register(cpu, 13, &reg13);
+ mips_cpu_get_register(cpu, 16, &reg16);
+ mips_cpu_get_register(cpu, 31, &reg31);
+
+ if(reg10 == 9+8 && reg13 == 13 && reg16 == 14+15) {
+ passed = 1;
+ }
+
+ if((opcode == 3 || opcode == 9) && reg31 != 8) {
+ passed = 0;
}
return passed;
}
-int test_load(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint8_t num) {
+int test_load(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t word) {
int passed = 0;
+ uint16_t half_word;
+ uint8_t byte;
uint32_t res;
+ half_word = (uint16_t)word;
+ byte = (uint8_t)word;
+
mips_cpu_reset(cpu);
uint32_t inst = change_endianness(gen_instruction(opcode, 8, 9, 4));
mips_mem_write(ram, 0, 4, (uint8_t*)&inst);
- mips_mem_write(ram, 0x30, 1, &num);
+
+ if(opcode == LB || opcode == LBU) {
+ mips_mem_write(ram, 0x30, 1, &byte);
+ } else if(opcode == LH || opcode == LHU) {
+ uint16_t tmp = (half_word<<8) | (half_word>>8);
+ mips_mem_write(ram, 0x30, 2, (uint8_t*)&tmp);
+ } else {
+ uint32_t tmp = change_endianness(word);
+ mips_mem_write(ram, 0x30, 4, (uint8_t*)&tmp);
+ }
mips_cpu_set_register(cpu, 8, 0x2c);
+ if(opcode == LWR) {
+ mips_cpu_set_register(cpu, 8, 0x2f);
+ }
+ mips_cpu_set_register(cpu, 9, 0xbabacdcd);
mips_cpu_step(cpu);
mips_cpu_get_register(cpu, 9, &res);
- if((res == (uint32_t)(int8_t)num && opcode == LB) || (res == (uint32_t)num && opcode == LBU)) {
+ if((res == (uint32_t)(int8_t)byte && opcode == LB) || (res == (uint32_t)byte && opcode == LBU) || (res == (uint32_t)(int16_t)half_word && opcode == LH) || (res == (uint32_t)half_word && opcode == LHU) || (res == word && opcode == LW) || (res == 4<<16 && opcode == LUI) || (res == ((word&0xffff)|(0xbaba0000)) && (opcode == LWR)) || (res == ((word&0xffff0000)|(0xcdcd)))) {
passed = 1;
}
return passed;
}
+int test_mult_div(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t num1, uint32_t num2) {
+ int passed = 0;
+ uint64_t result;
+ uint32_t hi, lo;
+
+ mips_cpu_reset(cpu);
+
+ uint32_t inst = change_endianness(gen_instruction(8, 9, 0, 0, opcode));
+ mips_mem_write(ram, 0, 4, (uint8_t*)&inst);
+ inst = change_endianness(gen_instruction(0, 0, 10, 0, MFHI));
+ mips_mem_write(ram, 4, 4, (uint8_t*)&inst);
+ inst = change_endianness(gen_instruction(0, 0, 11, 0, MFLO));
+ mips_mem_write(ram, 8, 4, (uint8_t*)&inst);
+
+ mips_cpu_set_register(cpu, 8, num1);
+ mips_cpu_set_register(cpu, 9, num2);
+ mips_cpu_set_register(cpu, 10, 0xabcde);
+ mips_cpu_set_register(cpu, 11, 0xf193b);
+
+ mips_cpu_step(cpu);
+ mips_cpu_step(cpu);
+ mips_cpu_step(cpu);
+
+ mips_cpu_get_register(cpu, 10, &hi);
+ mips_cpu_get_register(cpu, 11, &lo);
+
+ result = (((uint64_t)hi)<<32) | ((uint64_t)lo);
+
+ if((opcode == MULT && result == (uint64_t)((int64_t)(int32_t)num1*(int64_t)(int32_t)num2)) || (opcode == MULTU && result == (uint64_t)((uint32_t)num1)*(uint32_t)num2) || (opcode == DIV && lo == (uint32_t)((int32_t)num1/(int32_t)num2) && hi == (uint32_t)((int32_t)num1%(int32_t)num2)) || (opcode == DIVU && lo == num1/num2 && hi == num1%num2)) {
+ passed = 1;
+ }
+
+ return passed;
+}
diff --git a/src/ymh15/test_mips.o b/src/ymh15/test_mips.o
index e62b5d1..32a3fd1 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 a1d1a7f..054068b 100644
--- a/src/ymh15/test_mips_ymh15.hpp
+++ b/src/ymh15/test_mips_ymh15.hpp
@@ -6,8 +6,22 @@
#include <ctime>
// Functions
+#define SLL 0x0
+#define SRL 0x2
+#define SRA 0x3
+#define SLLV 0x4
+#define SRLV 0x6
+#define SRAV 0x7
#define JR 0x8
#define JALR 0x9
+#define MFHI 0x10
+#define MTHI 0x11
+#define MFLO 0x12
+#define MTLO 0x13
+#define MULT 0x18
+#define MULTU 0x19
+#define DIV 0x1a
+#define DIVU 0x1b
#define ADD 0x20
#define ADDU 0x21
#define SUB 0x22
@@ -15,9 +29,14 @@
#define AND 0x24
#define OR 0x25
#define XOR 0x26
+#define SLT 0x2a
+#define SLTU 0x2b
// OPcodes
#define BGEZ 0x1
+#define BGEZAL 0x1
+#define BLTZ 0x1
+#define BLTZAL 0x1
#define J 0x2
#define JAL 0x3
#define BEQ 0x4
@@ -26,11 +45,22 @@
#define BGTZ 0x7
#define ADDI 0x8
#define ADDIU 0x9
+#define SLTI 0xa
+#define SLTIU 0xb
#define ANDI 0xc
#define ORI 0xd
#define XORI 0xe
+#define LUI 0xf
#define LB 0x20
+#define LH 0x21
+#define LWL 0x22
+#define LW 0x23
#define LBU 0x24
+#define LHU 0x25
+#define LWR 0x26
+#define SB 0x28
+#define SH 0x29
+#define SW 0x2b
uint32_t gen_instruction(uint32_t src1, uint32_t src2, uint32_t dest,
uint32_t shift, uint32_t function);
@@ -46,6 +76,7 @@ int test_I(mips_mem_h ram, mips_cpu_h cpu, uint32_t type, uint32_t num1,
uint32_t num2);
int test_branch(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t a, uint8_t l, uint32_t opc2, uint32_t b);
int test_jump(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode);
-int test_load(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint8_t num);
+int test_load(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t word);
+int test_mult_div(mips_mem_h ram, mips_cpu_h cpu, uint32_t opcode, uint32_t num1, uint32_t num2);
#endif // TEST_MIPS_YMH15_H