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 <alekratz@gmail.com>
This commit is contained in:
2020-01-28 13:51:25 -05:00
parent 7e6c621c2b
commit f98a53654e
6 changed files with 63 additions and 29 deletions

View File

@@ -25,6 +25,6 @@ fn main() -> Result<()> {
process::exit(1); process::exit(1);
}, },
}; };
println!("{:?}", ast); println!("{:#?}", ast);
Ok(()) Ok(())
} }

View File

@@ -16,12 +16,13 @@ pub enum Inst {
CmpEq(Reg, Reg), CmpEq(Reg, Reg),
CmpLt(Reg, Reg), CmpLt(Reg, Reg),
Jmp(Reg),
Jz(Reg), Jz(Reg),
Jnz(Reg), Jnz(Reg),
Load(Reg, Reg), Load(Reg, Reg),
Store(Reg, Reg), Store(Reg, Reg),
StoreImm(Reg, u32), StoreImm(Reg, u64),
MemCopy(Reg, Reg), MemCopy(Reg, Reg),
RegCopy(Reg, Reg), RegCopy(Reg, Reg),

View File

@@ -1,4 +1,4 @@
use crate::vm::inst::Inst; use crate::vm::reg::Reg;
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub enum Line { pub enum Line {
@@ -18,3 +18,32 @@ pub enum Value {
Number(u64), Number(u64),
Label(String), 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,
}

View File

@@ -2,7 +2,6 @@ use std::str::FromStr;
use crate::vm::{ use crate::vm::{
syn::ast::*, syn::ast::*,
reg::*, reg::*,
inst::Inst,
}; };
grammar; grammar;
@@ -21,17 +20,17 @@ Label: String = {
} }
Number: u64 = { Number: u64 = {
<s:r"\$[0-9]+"> => u64::from_str(s).unwrap(), <s:r"\$[0-9]+"> => u64::from_str(&s[1..]).unwrap(),
<s:r"\$0x[0-9a-fA-F]+"> => u64::from_str_radix(s, 16).unwrap() <s:r"\$0x[0-9a-fA-F]+"> => u64::from_str_radix(&s[3..], 16).unwrap()
} }
Reg: Reg = { Reg: Reg = {
"%ip" => IP, r"%ip" => IP,
"%sp" => SP, r"%sp" => SP,
"%fp" => FP, r"%fp" => FP,
"%flags" => FLAGS, r"%flags" => FLAGS,
"%status" => STATUS, r"%status" => STATUS,
"%r[0-9]{2}" => { r"%r[0-9]{2}" => {
let offset = (&<>[2..]).parse::<u8>().unwrap(); let offset = (&<>[2..]).parse::<u8>().unwrap();
let reg = R00 + offset; let reg = R00 + offset;
assert!(reg < LAST_REG, "invalid register"); assert!(reg < LAST_REG, "invalid register");
@@ -52,16 +51,12 @@ Inst: Inst = {
"shr" <d:Reg> "," <s:Reg> => Inst::Shr(d, s), "shr" <d:Reg> "," <s:Reg> => Inst::Shr(d, s),
"cmpeq" <d:Reg> "," <s:Reg> => Inst::CmpEq(d, s), "cmpeq" <d:Reg> "," <s:Reg> => Inst::CmpEq(d, s),
"cmplt" <d:Reg> "," <s:Reg> => Inst::CmpLt(d, s), "cmplt" <d:Reg> "," <s:Reg> => Inst::CmpLt(d, s),
"jmp" <d:Reg> => Inst::Jmp(d),
"jz" <d:Reg> => Inst::Jz(d), "jz" <d:Reg> => Inst::Jz(d),
"jnz" <d:Reg> => Inst::Jnz(d), "jnz" <d:Reg> => Inst::Jnz(d),
"load" <d:Reg> "," <s:Reg> => Inst::Load(d, s), "load" <d:Reg> "," <s:Reg> => Inst::Load(d, s),
"store" <d:Reg> "," <s:Reg> => Inst::Store(d, s), "store" <d:Reg> "," <s:Reg> => Inst::Store(d, s),
"storeimm" <d:Reg> "," <s:Number> => { "storeimm" <d:Reg> "," <s:Value> => Inst::StoreImm(d, s),
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)
},
"memcopy" <d:Reg> "," <s:Reg> => Inst::MemCopy(d, s), "memcopy" <d:Reg> "," <s:Reg> => Inst::MemCopy(d, s),
"regcopy" <d:Reg> "," <s:Reg> => Inst::RegCopy(d, s), "regcopy" <d:Reg> "," <s:Reg> => Inst::RegCopy(d, s),
"nop" => Inst::Nop, "nop" => Inst::Nop,

View File

@@ -190,6 +190,10 @@ impl Vm {
self.remove_flags(Flags::COMPARE); self.remove_flags(Flags::COMPARE);
} }
} }
Inst::Jmp(r1) => {
let w1 = self.get_reg(r1);
self.set_reg(IP, w1);
}
Inst::Jz(r1) => { Inst::Jz(r1) => {
if !self.flags().contains(Flags::COMPARE) { if !self.flags().contains(Flags::COMPARE) {
let w1 = self.get_reg(r1); let w1 = self.get_reg(r1);

View File

@@ -2,19 +2,24 @@
.section code .section code
storeimm %r0, $0xDEAD main:
storeimm %r1, $16 storeimm %r00, $0xDEAD
storeimm %r01, $16
shl %r0, %r1 shl %r00, %r01
storeimm %r1, $0xBEEF storeimm %r01, $0xBEEF
or %r0, %r1 or %r00, %r01
storeimm %r1, $0xDEADBEEF storeimm %r01, $0xDEADBEEF
cmpeq %r0, %r1
jz failure
jmp ok storeimm %r00, failure
storeimm %r01, ok
cmpeq %r00, %r01
jz %r00
jmp %r01
failure: failure:
storeimm %status, $1 storeimm %status, $1