summaryrefslogtreecommitdiff
path: root/usr.bin/oemu/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/oemu/cpu.c')
-rw-r--r--usr.bin/oemu/cpu.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/usr.bin/oemu/cpu.c b/usr.bin/oemu/cpu.c
index 418febb..07ddc7b 100644
--- a/usr.bin/oemu/cpu.c
+++ b/usr.bin/oemu/cpu.c
@@ -198,6 +198,33 @@ cpu_div(struct oemu_cpu *cpu, inst_t *inst)
}
/*
+ * Decode the INST_DIV instruction
+ */
+static void
+cpu_br(struct oemu_cpu *cpu, inst_t *inst)
+{
+ struct cpu_regs *regs = &cpu->regs;
+ imm_t imm;
+ addr_t br_to;
+
+ if (inst->rd > NELEM(regs->xreg)) {
+ printf("bad register operand for 'br'\n");
+ return;
+ }
+
+ /*
+ * If we are branching to the reset vector, might
+ * as well reset all state.
+ */
+ br_to = regs->xreg[inst->rd];
+ if (br_to == 0) {
+ cpu_reset(cpu);
+ }
+
+ regs->ip = br_to;
+}
+
+/*
* Reset a CPU to a default state
*/
void
@@ -280,6 +307,9 @@ cpu_kick(struct oemu_cpu *cpu, struct sysmem *mem)
case INST_DIV:
cpu_div(cpu, inst);
break;
+ case INST_BR:
+ cpu_br(cpu, inst);
+ break;
}
/* Is this a halt instruction? */