use crate::vm::{reg::Reg, inst::*}; #[derive(Debug, Clone, PartialEq, Eq)] pub enum SectionBlock { Data { org: Option, body: Vec, }, Code { org: Option, body: Vec, }, 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()) } }