Add int and iret instruction definitions to the VM backend
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -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 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user