diff --git a/hbbytecode/instructions.in b/hbbytecode/instructions.in index 8e0d140..7a74d29 100644 --- a/hbbytecode/instructions.in +++ b/hbbytecode/instructions.in @@ -82,8 +82,8 @@ 0x51, BMC, RRH, "Copy block of memory" ; 0x52, BRC, RRB, "Copy register block" ; 0x53, JMP, O, "Relative jump" ; -0x54, JAL, RRA, "Linking absolute jump" ; -0x55, JALR, RRO, "Linking relative jump" ; +0x54, JAL, RRO, "Linking relative jump" ; +0x55, JALA, RRA, "Linking absolute jump" ; 0x56, JEQ, RRP, "Branch on equal" ; 0x57, JNE, RRP, "Branch on nonequal" ; 0x58, JLT, RRP, "Branch on lesser-than (signed)" ; diff --git a/hbvm/src/vmrun.rs b/hbvm/src/vmrun.rs index 37b6db8..98e549c 100644 --- a/hbvm/src/vmrun.rs +++ b/hbvm/src/vmrun.rs @@ -280,7 +280,16 @@ where JMP => handler!(self, |OpsO(off)| self.pc = self.pc.wrapping_add(off)), JAL => handler!(self, |OpsRRW(save, reg, offset)| { // Jump and link. Save PC after this instruction to - // specified register and jump to reg + offset. + // specified register and jump to reg + relative offset. + self.write_reg(save, self.pc.get()); + self.pc = self + .pc + .wrapping_add(self.read_reg(reg).cast::()) + .wrapping_add(offset); + }), + JALA => handler!(self, |OpsRRW(save, reg, offset)| { + // Jump and link. Save PC after this instruction to + // specified register and jump to reg self.write_reg(save, self.pc.get()); self.pc = Address::new( self.read_reg(reg).cast::().wrapping_add(offset.into()), @@ -400,7 +409,9 @@ where /// Bump instruction pointer #[inline(always)] fn bump_pc(&mut self) { - self.pc = self.pc.wrapping_add(core::mem::size_of::() + PAST_OP as usize); + self.pc = self + .pc + .wrapping_add(core::mem::size_of::() + PAST_OP as usize); } /// Decode instruction operands