diff --git a/hbvm/src/bytecode.rs b/hbvm/src/bytecode.rs index a9770c63..3c2014f3 100644 --- a/hbvm/src/bytecode.rs +++ b/hbvm/src/bytecode.rs @@ -9,47 +9,56 @@ macro_rules! constmod { } constmod!(pub opcode(u8) { - NOP = 0, // N - ADD = 1, // RRR - SUB = 2, // RRR - MUL = 3, // RRR - DIV = 4, // RRR - REM = 5, // RRR - AND = 6, // RRR - OR = 7, // RRR - XOR = 8, // RRR - NOT = 9, // RR + NOP = 0, // N; Do nothing + ADD = 1, // RRR; #0 ← #1 + #2 + SUB = 2, // RRR; #0 ← #1 - #2 + MUL = 3, // RRR; #0 ← #1 × #2 + DIV = 4, // RRR; #0 ← #1 ÷ #2 + REM = 5, // RRR; #0 ← #1 % #2 + AND = 6, // RRR; #0 ← #1 & #2 + OR = 7, // RRR; #0 ← #1 | #2 + XOR = 8, // RRR; #0 ← #1 ^ #2 + NOT = 9, // RR; #0 ← !#1 // TODO: Add instruction for integer and float // reg ← reg + imm instructions - ADDF = 10, // RRR - SUBF = 11, // RRR - MULF = 12, // RRR - DIVF = 13, // RRR + ADDF = 10, // RRR; #0 ← #1 +. #2 + SUBF = 11, // RRR; #0 ← #1 +. #2 + MULF = 12, // RRR; #0 ← #1 +. #2 + DIVF = 13, // RRR; #0 ← #1 +. #2 - LI = 14, // RI - LD = 15, // RI - ST = 16, // RI + CP = 14, // RR; Copy #0 ← #1 + LI = 15, // RI; Load immediate, #0 ← imm #1 + LB = 16, // RRI; Load byte (8 bits), #0 ← [#1 + imm #2] + LD = 17, // RRI; Load doublet (16 bits) + LQ = 18, // RRI; Load quadlet (32 bits) + LO = 19, // RRI; Load octlet (64 bits) + SB = 20, // RRI; Store byte, [#1 + imm #2] ← #0 + SD = 21, // RRI; Store doublet + SQ = 22, // RRI; Store quadlet + SO = 23, // RRI; Store octlet - MAPPAGE = 17, // ? - UNMAPPAGE = 18, // ? + PAGEMAP = 24, // ?; Map a page + PAGEUNMAP = 25, // ?; Unmap a page + PAGEMP = 26, // ?; Page modify protection flags - JMP = 100, // I - JMPCOND = 101, // I - RET = 103, // N - ECALL = 255, // N + JMP = 100, // I; Unconditional jump + JMPCOND = 101, // ?; Conditional jump + RET = 103, // N; Return + ECALL = 255, // N; Issue system call }); #[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8); +#[repr(packed)] pub struct ParamRRI(pub u8, pub u8, pub u64); #[repr(packed)] pub struct ParamRR(pub u8, pub u8); - #[repr(packed)] pub struct ParamRI(pub u8, pub u64); /// # Safety /// TODO. pub unsafe trait OpParam {} unsafe impl OpParam for ParamRRR {} +unsafe impl OpParam for ParamRRI {} unsafe impl OpParam for ParamRR {} unsafe impl OpParam for ParamRI {} unsafe impl OpParam for u64 {} diff --git a/hbvm/src/validate.rs b/hbvm/src/validate.rs index d6aacaa4..7a1c2675 100644 --- a/hbvm/src/validate.rs +++ b/hbvm/src/validate.rs @@ -48,7 +48,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> { rest } // RR - [NOT, _, _, rest @ ..] => { + [NOT | CP, _, _, rest @ ..] => { if let Some(n) = reg(&program[1..=2]) { bail!(InvalidRegister, start, program, n + 1) } @@ -61,7 +61,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> { } rest } - [LD | ST, ..] => bail!(Unimplemented, start, program), + [LD..=SO, ..] => bail!(Unimplemented, start, program), _ => bail!(InvalidInstruction, start, program), } } diff --git a/hbvm/src/vm/mod.rs b/hbvm/src/vm/mod.rs index 0275558d..57db9f57 100644 --- a/hbvm/src/vm/mod.rs +++ b/hbvm/src/vm/mod.rs @@ -75,11 +75,15 @@ impl<'a> Vm<'a> { SUBF => binary_op!(self, float, ops::Sub::sub), MULF => binary_op!(self, float, ops::Mul::mul), DIVF => binary_op!(self, float, ops::Div::div), + CP => { + let param = param!(self, ParamRR); + *self.reg_mut(param.0) = *self.reg(param.1); + } LI => { let param = param!(self, ParamRI); *self.reg_mut(param.0) = param.1.into(); } - // TODO: LD, ST + // TODO: Loads and stores JMP => { self.pc = self.program.as_ptr().add(self.pc + 1).cast::().read() as usize;