Files
pkgsrc-ng/emulators/gxemul/patches/patch-src_cpus_cpu_mips_instr.cc
2016-11-18 22:39:22 +01:00

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;