Use lrpar for parsing, big 'ol syntax overhaul
Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
146
src/vm/inst.rs
146
src/vm/inst.rs
@@ -1,3 +1,5 @@
|
||||
use crate::vm::{common::Addr, reg::Reg};
|
||||
|
||||
macro_rules! instructions {
|
||||
{
|
||||
$($variant:ident = $value:expr),* $(,)?
|
||||
@@ -20,43 +22,115 @@ macro_rules! instructions {
|
||||
pub type InstOp = u16;
|
||||
|
||||
instructions! {
|
||||
ADD = 0x0000,
|
||||
MUL = 0x0001,
|
||||
DIV = 0x0002,
|
||||
MOD = 0x0003,
|
||||
INEG = 0x0004,
|
||||
AND = 0x0005,
|
||||
OR = 0x0006,
|
||||
INV = 0x0007,
|
||||
NOT = 0x0008,
|
||||
XOR = 0x0009,
|
||||
SHL = 0x000a,
|
||||
SHR = 0x000b,
|
||||
CMPEQ = 0x1000,
|
||||
CMPLT = 0x1001,
|
||||
JMP = 0x1100,
|
||||
JZ = 0x1101,
|
||||
JNZ = 0x1102,
|
||||
LOAD = 0x2000,
|
||||
REGCOPY = 0x2001,
|
||||
STOREIMM64 = 0x2100,
|
||||
STOREIMM32 = 0x2101,
|
||||
MEMCOPY = 0x2200,
|
||||
STORE = 0x2201,
|
||||
HALT = 0xF000,
|
||||
NOP = 0xF001,
|
||||
ADD = 0x0000,
|
||||
SUB = 0x0001,
|
||||
MUL = 0x0002,
|
||||
DIV = 0x0003,
|
||||
MOD = 0x0004,
|
||||
AND = 0x0005,
|
||||
OR = 0x0006,
|
||||
XOR = 0x0007,
|
||||
SHL = 0x0008,
|
||||
SHR = 0x0009,
|
||||
INEG = 0x000a,
|
||||
INV = 0x000b,
|
||||
NOT = 0x000c,
|
||||
CMPEQ = 0x1000,
|
||||
CMPLT = 0x1001,
|
||||
JMP = 0x1002,
|
||||
JZ = 0x1003,
|
||||
JNZ = 0x1004,
|
||||
MOV = 0x2000,
|
||||
HALT = 0xF000,
|
||||
NOP = 0xF001,
|
||||
DUMP = 0xF002,
|
||||
}
|
||||
|
||||
pub fn inst_len(op: InstOp) -> usize {
|
||||
match op {
|
||||
// 2 bytes
|
||||
HALT | NOP => 2,
|
||||
// 4 bytes
|
||||
ADD | MUL | DIV | INEG | INV | NOT | MOD | AND | OR | XOR | SHL | SHR | CMPEQ | CMPLT
|
||||
| JMP | JZ | JNZ | LOAD | REGCOPY | MEMCOPY | STORE => 4,
|
||||
// Immediates - 4+ bytes
|
||||
STOREIMM64 => 16,
|
||||
STOREIMM32 => 8,
|
||||
_ => panic!("unknown instruction op 0x{:04x}", op),
|
||||
pub enum Inst {
|
||||
Add(Dest, Source),
|
||||
Sub(Dest, Source),
|
||||
Mul(Dest, Source),
|
||||
Div(Dest, Source),
|
||||
Mod(Dest, Source),
|
||||
And(Dest, Source),
|
||||
Or(Dest, Source),
|
||||
Xor(Dest, Source),
|
||||
Shl(Dest, Source),
|
||||
Shr(Dest, Source),
|
||||
INeg(Dest, Source),
|
||||
Inv(Dest, Source),
|
||||
Not(Dest, Source),
|
||||
CmpEq(Source, Source),
|
||||
CmpLt(Source, Source),
|
||||
Jmp(Source),
|
||||
Jz(Source),
|
||||
Jnz(Source),
|
||||
Mov(Dest, Source),
|
||||
Halt,
|
||||
Nop,
|
||||
Dump,
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
pub fn op(&self) -> InstOp {
|
||||
match self {
|
||||
Inst::Add(_, _) => ADD,
|
||||
Inst::Sub(_, _) => SUB,
|
||||
Inst::Mul(_, _) => MUL,
|
||||
Inst::Div(_, _) => DIV,
|
||||
Inst::Mod(_, _) => MOD,
|
||||
Inst::And(_, _) => AND,
|
||||
Inst::Or(_, _) => OR,
|
||||
Inst::Xor(_, _) => XOR,
|
||||
Inst::Shl(_, _) => SHL,
|
||||
Inst::Shr(_, _) => SHL,
|
||||
Inst::INeg(_, _) => INEG,
|
||||
Inst::Inv(_, _) => INV,
|
||||
Inst::Not(_, _) => NOT,
|
||||
Inst::CmpEq(_, _) => CMPEQ,
|
||||
Inst::CmpLt(_, _) => CMPLT,
|
||||
Inst::Jmp(_) => JMP,
|
||||
Inst::Jz(_) => JZ,
|
||||
Inst::Jnz(_) => JNZ,
|
||||
Inst::Mov(_, _) => MOV,
|
||||
Inst::Halt => HALT,
|
||||
Inst::Nop => NOP,
|
||||
Inst::Dump => DUMP,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Source {
|
||||
Addr64(Addr),
|
||||
Addr32(Addr),
|
||||
Addr16(Addr),
|
||||
Addr8(Addr),
|
||||
Reg(Reg),
|
||||
Imm(u64),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Dest {
|
||||
Addr64(Addr),
|
||||
Addr32(Addr),
|
||||
Addr16(Addr),
|
||||
Addr8(Addr),
|
||||
Reg(Reg),
|
||||
}
|
||||
|
||||
pub const DEST_ADDR64: u8 = 0b0000;
|
||||
pub const DEST_ADDR32: u8 = 0b0001;
|
||||
pub const DEST_ADDR16: u8 = 0b0010;
|
||||
pub const DEST_ADDR8: u8 = 0b0011;
|
||||
pub const DEST_REG: u8 = 0b0100;
|
||||
|
||||
pub const SOURCE_ADDR64: u8 = 0b0000;
|
||||
pub const SOURCE_ADDR32: u8 = 0b0001;
|
||||
pub const SOURCE_ADDR16: u8 = 0b0010;
|
||||
pub const SOURCE_ADDR8: u8 = 0b0011;
|
||||
pub const SOURCE_REG: u8 = 0b0100;
|
||||
pub const SOURCE_IMM64: u8 = 0b0101;
|
||||
pub const SOURCE_IMM32: u8 = 0b0110;
|
||||
pub const SOURCE_IMM16: u8 = 0b0111;
|
||||
pub const SOURCE_IMM8: u8 = 0b1000;
|
||||
|
||||
Reference in New Issue
Block a user