Major changes inlude: * Bit the bullet and now instructions have their length hard-coded * Move from_utf8 object parsing to be done by their objects (instead of a Parser god object) * A list of AST sections are assembled into an Object using the new vm::obj::assemble module. * Changed the object layout some in the spec, and adjusted code to match this. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
115 lines
2.5 KiB
Rust
115 lines
2.5 KiB
Rust
use crate::vm::{reg::Reg, inst::*};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum SectionBlock {
|
|
Data {
|
|
org: Option<SectionOrg>,
|
|
body: Vec<Line>,
|
|
},
|
|
Code {
|
|
org: Option<SectionOrg>,
|
|
body: Vec<Line>,
|
|
},
|
|
Meta {
|
|
entries: Vec<(String, ImmValue)>,
|
|
},
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub enum SectionOrg {
|
|
Start(u64),
|
|
Range(u64, u64),
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum Line {
|
|
Inst(Inst),
|
|
LabelDef(String),
|
|
ImmValue(ImmValue),
|
|
Export(String),
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum ImmValue {
|
|
Number(u64),
|
|
Label(String),
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum Inst {
|
|
Add(Reg, Reg),
|
|
Mul(Reg, Reg),
|
|
Div(Reg, Reg),
|
|
Mod(Reg, Reg),
|
|
INeg(Reg),
|
|
And(Reg, Reg),
|
|
Or(Reg, Reg),
|
|
Inv(Reg),
|
|
Not(Reg),
|
|
Xor(Reg, Reg),
|
|
Shl(Reg, Reg),
|
|
Shr(Reg, Reg),
|
|
|
|
CmpEq(Reg, Reg),
|
|
CmpLt(Reg, Reg),
|
|
Jmp(Reg),
|
|
Jz(Reg),
|
|
Jnz(Reg),
|
|
|
|
Load(Reg, Reg),
|
|
Store(Reg, Reg),
|
|
StoreImm(Reg, ImmValue),
|
|
MemCopy(Reg, Reg),
|
|
RegCopy(Reg, Reg),
|
|
|
|
Nop,
|
|
Halt,
|
|
}
|
|
|
|
impl Inst {
|
|
pub fn op(&self) -> InstOp {
|
|
match self {
|
|
Inst::Add(_, _) => { ADD }
|
|
Inst::Mul(_, _) => { MUL }
|
|
Inst::Div(_, _) => { DIV }
|
|
Inst::Mod(_, _) => { MOD }
|
|
Inst::INeg(_) => { INEG }
|
|
Inst::And(_, _) => { AND }
|
|
Inst::Or(_, _) => { OR }
|
|
Inst::Inv(_) => { INV }
|
|
Inst::Not(_) => { NOT }
|
|
Inst::Xor(_, _) => { XOR }
|
|
Inst::Shl(_, _) => { SHL }
|
|
Inst::Shr(_, _) => { SHR }
|
|
|
|
Inst::CmpEq(_, _) => { CMPEQ }
|
|
Inst::CmpLt(_, _) => { CMPLT }
|
|
Inst::Jmp(_) => { JMP }
|
|
Inst::Jz(_) => { JZ }
|
|
Inst::Jnz(_) => { JNZ }
|
|
|
|
Inst::Load(_, _) => { LOAD }
|
|
Inst::Store(_, _) => { STORE }
|
|
Inst::StoreImm(_, imm) => {
|
|
if let ImmValue::Number(imm) = imm {
|
|
if *imm > (u32::max_value() as u64) {
|
|
STOREIMM64
|
|
} else {
|
|
STOREIMM32
|
|
}
|
|
} else {
|
|
STOREIMM64
|
|
}
|
|
}
|
|
Inst::MemCopy(_, _) => { MEMCOPY }
|
|
Inst::RegCopy(_, _) => { REGCOPY }
|
|
|
|
Inst::Nop => { NOP }
|
|
Inst::Halt => { HALT }
|
|
}
|
|
}
|
|
pub fn len(&self) -> usize {
|
|
inst_len(self.op())
|
|
}
|
|
}
|