summaryrefslogtreecommitdiff
path: root/usr.bin/oemu/cpu.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-07-22 15:26:46 -0400
committerIan Moffett <ian@osmora.org>2025-07-22 15:26:46 -0400
commit7a38e4f8aac5cfe7a4503589a2cf8b953295e04b (patch)
tree0f9d835d6027f562821304d6499d9fec9b5f1f83 /usr.bin/oemu/cpu.c
parentfc65d46a2f82d54a6a24ea4cde9f4c2e0d0bb1a7 (diff)
oemu: cpu: Decode the BR instruction
Add support for interpreting the BR (branch) instruction. This instruction takes in a single register operand containing an address to reassign the instruction pointer to. Signed-off-by: Ian Moffett <ian@osmora.org>
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? */