提交 ebf7354e 编写于 作者: Z Zihao Yu

mips32: add cte

上级 717142d6
......@@ -5,6 +5,8 @@ void isa_difftest_syncregs() {
ref_difftest_setregs(&cpu);
}
#define check_reg(r) same = same && difftest_check_reg(str(r), pc, ref_r->r, cpu.r)
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
bool same = true;
if (memcmp(&cpu, ref_r, sizeof(cpu.gpr))) {
......@@ -14,7 +16,11 @@ bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc) {
}
same = false;
}
same = same && difftest_check_reg("pc", pc, ref_r->pc, cpu.pc);
check_reg(pc);
check_reg(lo);
check_reg(hi);
check_reg(status);
return same;
}
......
......@@ -25,6 +25,8 @@ make_EHelper(lwr);
make_EHelper(mfhi);
make_EHelper(mflo);
make_EHelper(mthi);
make_EHelper(mtlo);
make_EHelper(mul);
make_EHelper(mult);
make_EHelper(multu);
......@@ -44,3 +46,8 @@ make_EHelper(bgez);
make_EHelper(inv);
make_EHelper(nemu_trap);
make_EHelper(syscall);
make_EHelper(eret);
make_EHelper(mfc0);
make_EHelper(mtc0);
......@@ -3,8 +3,8 @@
static OpcodeEntry special_table [64] = {
/* b000 */ IDEX(shift, sll), EMPTY, IDEX(shift, srl), IDEX(shift, sra), IDEX(R, sll), EMPTY, IDEX(R, srl), IDEX(R, sra),
/* b001 */ IDEX(R, jr), IDEX(R, jalr), IDEX(cmov, movz), IDEX(cmov, movn), EMPTY, EMPTY, EMPTY, EMPTY,
/* b010 */ IDEX(R, mfhi), EMPTY, IDEX(R, mflo), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b001 */ IDEX(R, jr), IDEX(R, jalr), IDEX(cmov, movz), IDEX(cmov, movn), EX(syscall), EMPTY, EMPTY, EMPTY,
/* b010 */ IDEX(R, mfhi), IDEX(R, mthi), IDEX(R, mflo), IDEX(R, mtlo), EMPTY, EMPTY, EMPTY, EMPTY,
/* b011 */ IDEX(R, mult), IDEX(R, multu), IDEX(R, div), IDEX(R, divu), EMPTY, EMPTY, EMPTY, EMPTY,
/* b100 */ EMPTY, IDEX(R, add), EMPTY, IDEX(R, sub), IDEX(R, and), IDEX(R, or), IDEX(R, xor), IDEX(R, nor),
/* b101 */ EMPTY, EMPTY, IDEX(R, slt), IDEX(R, sltu), EMPTY, EMPTY, EMPTY, EMPTY,
......@@ -42,10 +42,35 @@ static make_EHelper(regimm) {
idex(eip, &regimm_table[decinfo.isa.instr.rt]);
}
static OpcodeEntry cop0_table [16] = {
/* b00 */ IDEX(R, mfc0), EMPTY, EMPTY, EMPTY, IDEX(R, mtc0), EMPTY, EMPTY, EMPTY,
/* b01 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
};
static OpcodeEntry cop0co_table [64] = {
/* b000 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b001 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b010 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b011 */ EX(eret), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b100 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b101 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b110 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b111 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
};
static make_EHelper(cop0) {
if (decinfo.isa.instr.rs & 0x10) {
idex(eip, &cop0co_table[decinfo.isa.instr.func]);
}
else {
idex(eip, &cop0_table[decinfo.isa.instr.rs]);
}
}
static OpcodeEntry opcode_table [64] = {
/* b000 */ EX(special), EX(regimm), IDEX(J, j), IDEX(J, jal), IDEX(B, beq), IDEX(B, bne), IDEX(B, blez), IDEX(B, bgtz),
/* b001 */ EMPTY, IDEX(I, add), IDEX(I, slt), IDEX(I, sltu), IDEX(IU, and), IDEX(IU, or), IDEX(IU, xor), IDEX(IU, lui),
/* b010 */ EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b010 */ EX(cop0), EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
/* b011 */ EMPTY, EMPTY, EMPTY, EMPTY, EX(special2), EMPTY, EMPTY, EMPTY,
/* b100 */ IDEXW(ld, lds, 1), IDEXW(ld, lds, 2), IDEX(st, lwl), IDEXW(ld, ld, 4), IDEXW(ld, ld, 1), IDEXW(ld, ld, 2), IDEX(st, lwr), EMPTY,
/* b101 */ IDEXW(st, st, 1), IDEXW(st, st, 2), IDEX(st, swl), IDEXW(st, st, 4), EMPTY, EMPTY, IDEX(st, swr), EMPTY,
......
......@@ -12,6 +12,18 @@ make_EHelper(mflo) {
print_asm_template3(mflo);
}
make_EHelper(mthi) {
rtl_mv(&cpu.hi, &id_src->val);
print_asm_template2(mthi);
}
make_EHelper(mtlo) {
rtl_mv(&cpu.lo, &id_src->val);
print_asm_template2(mtlo);
}
make_EHelper(mul) {
rtl_imul_lo(&s0, &id_src->val, &id_src2->val);
rtl_sr(id_dest->reg, &s0, 4);
......
#include "cpu/exec.h"
void raise_intr(uint8_t, vaddr_t);
#define EX_SYSCALL 8
make_EHelper(syscall) {
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
raise_intr(EX_SYSCALL, cpu.pc);
print_asm("syscall");
}
make_EHelper(eret) {
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
rtl_li(&s0, cpu.epc);
rtl_jr(&s0);
print_asm("eret");
}
make_EHelper(mfc0) {
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
uint32_t val;
char *name;
switch (id_dest->reg) {
case 12: val = cpu.status; name = "status"; break;
case 13: val = cpu.cause; name = "cause"; break;
case 14: val = cpu.epc; name = "epc"; break;
default: assert(0);
}
rtl_li(&s0, val);
rtl_sr(id_src2->reg, &s0, 4);
print_asm("mfc0 %s, %s", id_src2->str, name);
}
make_EHelper(mtc0) {
#if defined(DIFF_TEST)
difftest_skip_ref();
#endif
char *name;
switch (id_dest->reg) {
case 12: cpu.status = id_src2->val; name = "status"; break;
case 13: cpu.cause = id_src2->val; name = "cause"; break;
case 14: cpu.epc = id_src2->val; name = "epc"; break;
default: assert(0);
}
print_asm("mtc0 %s, %s", id_src2->str, name);
}
......@@ -17,6 +17,7 @@ typedef struct {
uint32_t badvaddr;
uint32_t cause;
vaddr_t pc;
uint32_t epc;
bool INTR;
} CPU_state;
......
#include "cpu/rtl.h"
//#include "isa/mmu.h"
void raise_intr(uint8_t NO, vaddr_t ret_addr) {
#define EX_ENTRY 0x180
void raise_intr(uint8_t NO, vaddr_t epc) {
/* TODO: Trigger an interrupt/exception with ``NO''.
* That is, use ``NO'' to index the IDT.
*/
//TODO();
cpu.cause = NO << 2;
cpu.epc = epc;
rtl_j(EX_ENTRY);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册