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:
@@ -25,6 +25,6 @@ fn main() -> Result<()> {
|
||||
process::exit(1);
|
||||
},
|
||||
};
|
||||
println!("{:?}", ast);
|
||||
println!("{:#?}", ast);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
<s:r"\$[0-9]+"> => u64::from_str(s).unwrap(),
|
||||
<s:r"\$0x[0-9a-fA-F]+"> => u64::from_str_radix(s, 16).unwrap()
|
||||
<s:r"\$[0-9]+"> => u64::from_str(&s[1..]).unwrap(),
|
||||
<s:r"\$0x[0-9a-fA-F]+"> => 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::<u8>().unwrap();
|
||||
let reg = R00 + offset;
|
||||
assert!(reg < LAST_REG, "invalid register");
|
||||
@@ -52,16 +51,12 @@ Inst: Inst = {
|
||||
"shr" <d:Reg> "," <s:Reg> => Inst::Shr(d, s),
|
||||
"cmpeq" <d:Reg> "," <s:Reg> => Inst::CmpEq(d, s),
|
||||
"cmplt" <d:Reg> "," <s:Reg> => Inst::CmpLt(d, s),
|
||||
"jmp" <d:Reg> => Inst::Jmp(d),
|
||||
"jz" <d:Reg> => Inst::Jz(d),
|
||||
"jnz" <d:Reg> => Inst::Jnz(d),
|
||||
"load" <d:Reg> "," <s:Reg> => Inst::Load(d, s),
|
||||
"store" <d:Reg> "," <s:Reg> => Inst::Store(d, s),
|
||||
"storeimm" <d:Reg> "," <s:Number> => {
|
||||
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" <d:Reg> "," <s:Value> => Inst::StoreImm(d, s),
|
||||
"memcopy" <d:Reg> "," <s:Reg> => Inst::MemCopy(d, s),
|
||||
"regcopy" <d:Reg> "," <s:Reg> => Inst::RegCopy(d, s),
|
||||
"nop" => Inst::Nop,
|
||||
|
||||
@@ -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);
|
||||
|
||||
23
test.asm
23
test.asm
@@ -2,19 +2,24 @@
|
||||
|
||||
.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
|
||||
|
||||
Reference in New Issue
Block a user