From f98a53654ef6202c1cd9202b035226e2e5ef53d8 Mon Sep 17 00:00:00 2001 From: Alek Ratzloff Date: Tue, 28 Jan 2020 13:51:25 -0500 Subject: [PATCH] Update/add instructions in parser * StoreImm just uses a u64 instead of u32 - we'll figure out the layout later * Jmp implementation added (can't believe I forgot this) * Add Inst AST item, whose immediates don't have to be a u64 right away Signed-off-by: Alek Ratzloff --- src/main.rs | 2 +- src/vm/inst.rs | 3 ++- src/vm/syn/ast.rs | 31 ++++++++++++++++++++++++++++++- src/vm/syn/parser.lalrpop | 25 ++++++++++--------------- src/vm/vm.rs | 4 ++++ test.asm | 27 ++++++++++++++++----------- 6 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/main.rs b/src/main.rs index 28c6a39..818e7e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,6 @@ fn main() -> Result<()> { process::exit(1); }, }; - println!("{:?}", ast); + println!("{:#?}", ast); Ok(()) } diff --git a/src/vm/inst.rs b/src/vm/inst.rs index 8604c4c..b888a4c 100644 --- a/src/vm/inst.rs +++ b/src/vm/inst.rs @@ -16,12 +16,13 @@ pub enum Inst { CmpEq(Reg, Reg), CmpLt(Reg, Reg), + Jmp(Reg), Jz(Reg), Jnz(Reg), Load(Reg, Reg), Store(Reg, Reg), - StoreImm(Reg, u32), + StoreImm(Reg, u64), MemCopy(Reg, Reg), RegCopy(Reg, Reg), diff --git a/src/vm/syn/ast.rs b/src/vm/syn/ast.rs index e41a27a..b81cce0 100644 --- a/src/vm/syn/ast.rs +++ b/src/vm/syn/ast.rs @@ -1,4 +1,4 @@ -use crate::vm::inst::Inst; +use crate::vm::reg::Reg; #[derive(Debug, Clone, PartialEq, Eq)] pub enum Line { @@ -18,3 +18,32 @@ pub enum Value { 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), + 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, Value), + MemCopy(Reg, Reg), + RegCopy(Reg, Reg), + + Nop, + Halt, +} diff --git a/src/vm/syn/parser.lalrpop b/src/vm/syn/parser.lalrpop index 60425fc..7a0931c 100644 --- a/src/vm/syn/parser.lalrpop +++ b/src/vm/syn/parser.lalrpop @@ -2,7 +2,6 @@ use std::str::FromStr; use crate::vm::{ syn::ast::*, reg::*, - inst::Inst, }; grammar; @@ -21,17 +20,17 @@ Label: String = { } Number: u64 = { - => u64::from_str(s).unwrap(), - => u64::from_str_radix(s, 16).unwrap() + => u64::from_str(&s[1..]).unwrap(), + => u64::from_str_radix(&s[3..], 16).unwrap() } Reg: Reg = { - "%ip" => IP, - "%sp" => SP, - "%fp" => FP, - "%flags" => FLAGS, - "%status" => STATUS, - "%r[0-9]{2}" => { + r"%ip" => IP, + r"%sp" => SP, + r"%fp" => FP, + r"%flags" => FLAGS, + r"%status" => STATUS, + r"%r[0-9]{2}" => { let offset = (&<>[2..]).parse::().unwrap(); let reg = R00 + offset; assert!(reg < LAST_REG, "invalid register"); @@ -52,16 +51,12 @@ Inst: Inst = { "shr" "," => Inst::Shr(d, s), "cmpeq" "," => Inst::CmpEq(d, s), "cmplt" "," => Inst::CmpLt(d, s), + "jmp" => Inst::Jmp(d), "jz" => Inst::Jz(d), "jnz" => Inst::Jnz(d), "load" "," => Inst::Load(d, s), "store" "," => Inst::Store(d, s), - "storeimm" "," => { - if s > u32::max_value() as u64 { - eprintln!("WARNING: number {} is too large. It will be truncated to 32 bits.", s); - } - Inst::StoreImm(d, (s & 0xFFFF_FFFF) as u32) - }, + "storeimm" "," => Inst::StoreImm(d, s), "memcopy" "," => Inst::MemCopy(d, s), "regcopy" "," => Inst::RegCopy(d, s), "nop" => Inst::Nop, diff --git a/src/vm/vm.rs b/src/vm/vm.rs index d069e93..cf566f0 100644 --- a/src/vm/vm.rs +++ b/src/vm/vm.rs @@ -190,6 +190,10 @@ impl Vm { self.remove_flags(Flags::COMPARE); } } + Inst::Jmp(r1) => { + let w1 = self.get_reg(r1); + self.set_reg(IP, w1); + } Inst::Jz(r1) => { if !self.flags().contains(Flags::COMPARE) { let w1 = self.get_reg(r1); diff --git a/test.asm b/test.asm index 08af873..c9394c3 100644 --- a/test.asm +++ b/test.asm @@ -2,22 +2,27 @@ .section code -storeimm %r0, $0xDEAD -storeimm %r1, $16 +main: + storeimm %r00, $0xDEAD + storeimm %r01, $16 -shl %r0, %r1 + shl %r00, %r01 -storeimm %r1, $0xBEEF -or %r0, %r1 + storeimm %r01, $0xBEEF + or %r00, %r01 -storeimm %r1, $0xDEADBEEF -cmpeq %r0, %r1 -jz failure + storeimm %r01, $0xDEADBEEF -jmp ok + storeimm %r00, failure + storeimm %r01, ok + cmpeq %r00, %r01 + + jz %r00 + + jmp %r01 failure: -storeimm %status, $1 -halt + storeimm %status, $1 + halt ok: