diff --git a/hbasm/src/lib.rs b/hbasm/src/lib.rs index 75a5731..391b251 100644 --- a/hbasm/src/lib.rs +++ b/hbasm/src/lib.rs @@ -21,11 +21,11 @@ macros::impl_both!( => [LD, ST], bbd(p0: R, p1: R, p2: I) => [ADDI, MULI, ANDI, ORI, XORI, SLI, SRI, SRSI, CMPI, CMPUI, - BMC, JEQ, JNE, JLT, JGT, JLTU, JGTU, ADDFI, MULFI], + BMC, JAL, JEQ, JNE, JLT, JGT, JLTU, JGTU, ADDFI, MULFI], bb(p0: R, p1: R) => [NEG, NOT, CP, SWA, NEGF, ITF, FTI], bd(p0: R, p1: I) - => [LI, JMP], + => [LI], n() => [NOP, ECALL], ); diff --git a/hbbytecode/src/lib.rs b/hbbytecode/src/lib.rs index 19f4648..9b4f60b 100644 --- a/hbbytecode/src/lib.rs +++ b/hbbytecode/src/lib.rs @@ -54,7 +54,7 @@ constmod!(pub opcode(u8) { BMC = 30, "BBD; [#0] ← [#1], imm #2 bytes"; BRC = 31, "BBB; #0 ← #1, imm #2 registers"; - JMP = 32, "BD; Unconditional jump [#0 + imm #1]"; + JAL = 32, "BD; Copy PC to #0 and unconditional jump [#1 + imm #2]"; JEQ = 33, "BBD; if #0 = #1 → jump imm #2"; JNE = 34, "BBD; if #0 ≠ #1 → jump imm #2"; JLT = 35, "BBD; if #0 < #1 → jump imm #2"; diff --git a/hbvm/src/validate.rs b/hbvm/src/validate.rs index 52f726f..d75306b 100644 --- a/hbvm/src/validate.rs +++ b/hbvm/src/validate.rs @@ -50,8 +50,8 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> { | [DIR | DIRF, _, _, _, _, rest @ ..] | [ADD..=CMPU | BRC | ADDF..=MULF, _, _, _, rest @ ..] | [NEG..=NOT | CP..=SWA | NEGF..=FTI, _, _, rest @ ..] - | [LI | JMP, _, _, _, _, _, _, _, _, _, rest @ ..] - | [ADDI..=CMPUI | BMC | JEQ..=JGTU | ADDFI..=MULFI, _, _, _, _, _, _, _, _, _, _, rest @ ..] + | [LI, _, _, _, _, _, _, _, _, _, rest @ ..] + | [ADDI..=CMPUI | BMC | JAL..=JGTU | ADDFI..=MULFI, _, _, _, _, _, _, _, _, _, _, rest @ ..] | [LD..=ST, _, _, _, _, _, _, _, _, _, _, _, _, rest @ ..] => rest, _ => { return Err(Error { diff --git a/hbvm/src/vm/mod.rs b/hbvm/src/vm/mod.rs index 7c3a50f..5e99360 100644 --- a/hbvm/src/vm/mod.rs +++ b/hbvm/src/vm/mod.rs @@ -259,8 +259,9 @@ impl<'a, PfHandler: HandlePageFault, const TIMER_QUOTIENT: usize> usize::from(count * 8), ); } - JMP => { - let ParamBD(reg, offset) = param!(self, ParamBD); + JAL => { + let ParamBBD(save, reg, offset) = param!(self, ParamBBD); + self.write_reg(save, self.pc as u64); self.pc = (self.read_reg(reg).as_u64() + offset) as usize; } JEQ => cond_jump!(self, int, Equal), diff --git a/spec.md b/spec.md index 4c64f26..55c3aaa 100644 --- a/spec.md +++ b/spec.md @@ -153,7 +153,7 @@ | Opcode | Name | Action | |:------:|:----:|:--------------------------------:| -| 30 | BMC | `[#0] ← [#1], copy imm #2 bytes` | +| 30 | BMC | `[#1] ← [#0], copy imm #2 bytes` | ### Register copy - Type BBB @@ -161,16 +161,16 @@ | Opcode | Name | Action | |:------:|:----:|:--------------------------------:| -| 31 | BRC | `#0 ← #1, copy imm #2 registers` | +| 31 | BRC | `#1 ← #0, copy imm #2 registers` | ## Control flow ### Unconditional jump -- Type BD +- Type BBD -| Opcode | Name | Action | -|:------:|:----:|:---------------------:| -| 32 | JMP | Jump at `#0 + imm #1` | +| Opcode | Name | Action | +|:------:|:----:|:-------------------------------------------------:| +| 32 | JAL | Save current PC to `#0` and jump at `#1 + imm #2` | ### Conditional jumps - Type BBD