Implement copy + docs for instructions

This commit is contained in:
Erin 2023-06-07 00:02:27 +02:00 committed by ondra05
parent 8d6e7af9d8
commit 8675965ef5
3 changed files with 40 additions and 27 deletions

View file

@ -9,47 +9,56 @@ macro_rules! constmod {
} }
constmod!(pub opcode(u8) { constmod!(pub opcode(u8) {
NOP = 0, // N NOP = 0, // N; Do nothing
ADD = 1, // RRR ADD = 1, // RRR; #0 ← #1 + #2
SUB = 2, // RRR SUB = 2, // RRR; #0 ← #1 - #2
MUL = 3, // RRR MUL = 3, // RRR; #0 ← #1 × #2
DIV = 4, // RRR DIV = 4, // RRR; #0 ← #1 ÷ #2
REM = 5, // RRR REM = 5, // RRR; #0 ← #1 % #2
AND = 6, // RRR AND = 6, // RRR; #0 ← #1 & #2
OR = 7, // RRR OR = 7, // RRR; #0 ← #1 | #2
XOR = 8, // RRR XOR = 8, // RRR; #0 ← #1 ^ #2
NOT = 9, // RR NOT = 9, // RR; #0 ← !#1
// TODO: Add instruction for integer and float // TODO: Add instruction for integer and float
// reg ← reg + imm instructions // reg ← reg + imm instructions
ADDF = 10, // RRR ADDF = 10, // RRR; #0 ← #1 +. #2
SUBF = 11, // RRR SUBF = 11, // RRR; #0 ← #1 +. #2
MULF = 12, // RRR MULF = 12, // RRR; #0 ← #1 +. #2
DIVF = 13, // RRR DIVF = 13, // RRR; #0 ← #1 +. #2
LI = 14, // RI CP = 14, // RR; Copy #0 ← #1
LD = 15, // RI LI = 15, // RI; Load immediate, #0 ← imm #1
ST = 16, // RI 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, // ? PAGEMAP = 24, // ?; Map a page
UNMAPPAGE = 18, // ? PAGEUNMAP = 25, // ?; Unmap a page
PAGEMP = 26, // ?; Page modify protection flags
JMP = 100, // I JMP = 100, // I; Unconditional jump
JMPCOND = 101, // I JMPCOND = 101, // ?; Conditional jump
RET = 103, // N RET = 103, // N; Return
ECALL = 255, // N ECALL = 255, // N; Issue system call
}); });
#[repr(packed)] pub struct ParamRRR(pub u8, pub u8, pub u8); #[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 ParamRR(pub u8, pub u8);
#[repr(packed)] pub struct ParamRI(pub u8, pub u64); #[repr(packed)] pub struct ParamRI(pub u8, pub u64);
/// # Safety /// # Safety
/// TODO. /// TODO.
pub unsafe trait OpParam {} pub unsafe trait OpParam {}
unsafe impl OpParam for ParamRRR {} unsafe impl OpParam for ParamRRR {}
unsafe impl OpParam for ParamRRI {}
unsafe impl OpParam for ParamRR {} unsafe impl OpParam for ParamRR {}
unsafe impl OpParam for ParamRI {} unsafe impl OpParam for ParamRI {}
unsafe impl OpParam for u64 {} unsafe impl OpParam for u64 {}

View file

@ -48,7 +48,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
rest rest
} }
// RR // RR
[NOT, _, _, rest @ ..] => { [NOT | CP, _, _, rest @ ..] => {
if let Some(n) = reg(&program[1..=2]) { if let Some(n) = reg(&program[1..=2]) {
bail!(InvalidRegister, start, program, n + 1) bail!(InvalidRegister, start, program, n + 1)
} }
@ -61,7 +61,7 @@ pub fn validate(mut program: &[u8]) -> Result<(), Error> {
} }
rest rest
} }
[LD | ST, ..] => bail!(Unimplemented, start, program), [LD..=SO, ..] => bail!(Unimplemented, start, program),
_ => bail!(InvalidInstruction, start, program), _ => bail!(InvalidInstruction, start, program),
} }
} }

View file

@ -75,11 +75,15 @@ impl<'a> Vm<'a> {
SUBF => binary_op!(self, float, ops::Sub::sub), SUBF => binary_op!(self, float, ops::Sub::sub),
MULF => binary_op!(self, float, ops::Mul::mul), MULF => binary_op!(self, float, ops::Mul::mul),
DIVF => binary_op!(self, float, ops::Div::div), DIVF => binary_op!(self, float, ops::Div::div),
CP => {
let param = param!(self, ParamRR);
*self.reg_mut(param.0) = *self.reg(param.1);
}
LI => { LI => {
let param = param!(self, ParamRI); let param = param!(self, ParamRI);
*self.reg_mut(param.0) = param.1.into(); *self.reg_mut(param.0) = param.1.into();
} }
// TODO: LD, ST // TODO: Loads and stores
JMP => { JMP => {
self.pc = self.pc =
self.program.as_ptr().add(self.pc + 1).cast::<u64>().read() as usize; self.program.as_ptr().add(self.pc + 1).cast::<u64>().read() as usize;