138 lines
3.8 KiB
C++
138 lines
3.8 KiB
C++
$NetBSD: patch-src_cpus_cpu_mips_instr.cc,v 1.1 2016/03/29 19:03:07 mrg Exp $
|
|
|
|
implement trap with immediate instructions present in MIPS32.
|
|
|
|
--- src/cpus/cpu_mips_instr.cc.orig 2016-03-28 11:59:41.000000000 -0700
|
|
+++ src/cpus/cpu_mips_instr.cc 2016-03-28 12:04:07.000000000 -0700
|
|
@@ -1461,6 +1461,92 @@
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * 1-register + 1-immediate:
|
|
+ *
|
|
+ * arg[0] = ptr to rs
|
|
+ * arg[1] = ([u]int16_t) immediate value
|
|
+ */
|
|
+
|
|
+X(tgei)
|
|
+{
|
|
+ MODE_int_t a = reg(ic->arg[0]), b = (int16_t)ic->arg[1];
|
|
+ if (a >= b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+X(tgeiu)
|
|
+{
|
|
+ MODE_uint_t a = reg(ic->arg[0]), b = ic->arg[1];
|
|
+ if (a >= b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+X(tlti)
|
|
+{
|
|
+ MODE_int_t a = reg(ic->arg[0]), b = (int16_t)ic->arg[1];
|
|
+ if (a < b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+X(tltiu)
|
|
+{
|
|
+ MODE_uint_t a = reg(ic->arg[0]), b = ic->arg[1];
|
|
+ if (a < b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+X(teqi)
|
|
+{
|
|
+ MODE_uint_t a = reg(ic->arg[0]), b = (int16_t)ic->arg[1];
|
|
+ if (a == b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+X(tnei)
|
|
+{
|
|
+ MODE_uint_t a = reg(ic->arg[0]), b = ic->arg[1];
|
|
+ if (a != b) {
|
|
+ /* Synch. PC and cause an exception: */
|
|
+ int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page)
|
|
+ / sizeof(struct mips_instr_call);
|
|
+ cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1)
|
|
+ << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT);
|
|
+ mips_cpu_exception(cpu, EXCEPTION_TR, 0, 0, 0, 0, 0, 0);
|
|
+ }
|
|
+}
|
|
+
|
|
|
|
/*
|
|
* 3-register arithmetic instructions:
|
|
@@ -4446,6 +4532,37 @@
|
|
}
|
|
break;
|
|
|
|
+ case REGIMM_TGEI:
|
|
+ case REGIMM_TGEIU:
|
|
+ case REGIMM_TLTI:
|
|
+ case REGIMM_TLTIU:
|
|
+ case REGIMM_TEQI:
|
|
+ case REGIMM_TNEI:
|
|
+ switch (rt) {
|
|
+ case REGIMM_TGEI:
|
|
+ ic->f = instr(tgei);
|
|
+ break;
|
|
+ case REGIMM_TGEIU:
|
|
+ ic->f = instr(tgeiu);
|
|
+ break;
|
|
+ case REGIMM_TLTI:
|
|
+ ic->f = instr(tlti);
|
|
+ break;
|
|
+ case REGIMM_TLTIU:
|
|
+ ic->f = instr(tltiu);
|
|
+ break;
|
|
+ case REGIMM_TEQI:
|
|
+ ic->f = instr(teqi);
|
|
+ break;
|
|
+ case REGIMM_TNEI:
|
|
+ ic->f = instr(tnei);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ ic->arg[0] = (size_t)&cpu->cd.mips.gpr[rs];
|
|
+ ic->arg[1] = imm;
|
|
+ break;
|
|
+
|
|
default:if (!cpu->translation_readahead)
|
|
fatal("UNIMPLEMENTED regimm rt=%i\n", rt);
|
|
goto bad;
|