Use lrpar for parsing, big 'ol syntax overhaul

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-02-17 16:15:06 -05:00
parent cf9ba376aa
commit 2c4b56e362
23 changed files with 1394 additions and 1494 deletions

View File

@@ -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;