Add int and iret instruction definitions to the VM backend

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-03-06 12:30:49 -05:00
parent 1fb2a1df44
commit 34b1147fe6
3 changed files with 49 additions and 29 deletions

View File

@@ -23,33 +23,35 @@ macro_rules! instructions {
pub type InstOp = u16; pub type InstOp = u16;
instructions! { instructions! {
ADD = 0x0000, ADD = 0x0000,
SUB = 0x0001, SUB = 0x0001,
MUL = 0x0002, MUL = 0x0002,
DIV = 0x0003, DIV = 0x0003,
IDIV = 0x0004, IDIV = 0x0004,
MOD = 0x0005, MOD = 0x0005,
AND = 0x0006, AND = 0x0006,
OR = 0x0007, OR = 0x0007,
XOR = 0x0008, XOR = 0x0008,
SHL = 0x0009, SHL = 0x0009,
SHR = 0x000a, SHR = 0x000a,
INEG = 0x000b, INEG = 0x000b,
INV = 0x000c, INV = 0x000c,
NOT = 0x000d, NOT = 0x000d,
CMPEQ = 0x1000, CMPEQ = 0x1000,
CMPLT = 0x1001, CMPLT = 0x1001,
JMP = 0x1002, JMP = 0x1002,
JZ = 0x1003, JZ = 0x1003,
JNZ = 0x1004, JNZ = 0x1004,
CALL = 0x2000, CALL = 0x2000,
RET = 0x2001, RET = 0x2001,
PUSH = 0x2002, PUSH = 0x2002,
POP = 0x2003, POP = 0x2003,
MOV = 0x3000, INT = 0x2004,
HALT = 0xF000, IRET = 0x2005,
NOP = 0xF001, MOV = 0x3000,
DUMP = 0xF002, HALT = 0xF000,
NOP = 0xF001,
DUMP = 0xF002,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@@ -77,6 +79,8 @@ pub enum Inst {
Ret, Ret,
Push(Source), Push(Source),
Pop(Dest), Pop(Dest),
Int(Source, Source),
IRet,
Mov(Dest, Source), Mov(Dest, Source),
Halt, Halt,
Nop, Nop,
@@ -110,6 +114,8 @@ impl Inst {
Inst::Ret => RET, Inst::Ret => RET,
Inst::Push(_) => PUSH, Inst::Push(_) => PUSH,
Inst::Pop(_) => POP, Inst::Pop(_) => POP,
Inst::Int(_, _) => INT,
Inst::IRet => IRET,
Inst::Halt => HALT, Inst::Halt => HALT,
Inst::Nop => NOP, Inst::Nop => NOP,
Inst::Dump => DUMP, Inst::Dump => DUMP,
@@ -134,7 +140,8 @@ impl Inst {
| Inst::Not(dest, source) | Inst::Not(dest, source)
| Inst::Mov(dest, source) => { 3 + dest.len() + source.len() } | Inst::Mov(dest, source) => { 3 + dest.len() + source.len() }
Inst::CmpEq(s1, s2) Inst::CmpEq(s1, s2)
| Inst::CmpLt(s1, s2) => { 3 + s1.len() + s2.len() } | Inst::CmpLt(s1, s2)
| Inst::Int(s1, s2) => { 3 + s1.len() + s2.len() }
Inst::Jmp(v) Inst::Jmp(v)
| Inst::Jz(v) | Inst::Jz(v)
| Inst::Jnz(v) | Inst::Jnz(v)
@@ -144,7 +151,8 @@ impl Inst {
Inst::Ret Inst::Ret
| Inst::Halt | Inst::Halt
| Inst::Nop | Inst::Nop
| Inst::Dump => { 2 } | Inst::Dump
| Inst::IRet => { 2 }
} }
} }
} }

View File

@@ -121,6 +121,8 @@ impl<T> MemCursor<T>
RET => Ok(Inst::Ret), RET => Ok(Inst::Ret),
PUSH => source!(Push), PUSH => source!(Push),
POP => dest!(Pop), POP => dest!(Pop),
INT => { todo!("INT decode") },
IRET => { todo!("IRET decode") },
MOV => dest_source!(Mov), MOV => dest_source!(Mov),
HALT => Ok(Inst::Halt), HALT => Ok(Inst::Halt),
NOP => Ok(Inst::Nop), NOP => Ok(Inst::Nop),

View File

@@ -356,6 +356,16 @@ impl State {
Inst::Pop(d) => { Inst::Pop(d) => {
self.pop(d)?; self.pop(d)?;
} }
Inst::Int(v, a) => {
let vector = self.load_source(v)?;
let aux = self.load_source(a)?;
// this method immediately jumps, so don't let the next_ip be set below
return self.interrupt(next_ip, vector as usize, aux);
}
Inst::IRet => {
// this method immediately jumps, so don't let the next_ip be set below
return self.exit_interrupt();
}
Inst::Mov(d, s) => { Inst::Mov(d, s) => {
let value = self.load_source(s)?; let value = self.load_source(s)?;
self.store_dest(d, value)?; self.store_dest(d, value)?;