From 36df43e3be361ca1d9f33691b3c36f3f95af0302 Mon Sep 17 00:00:00 2001 From: Cassie Jones Date: Sat, 11 Jan 2020 03:52:38 -0500 Subject: [PATCH] Add instruction encoder --- toolchain/src/inst.rs | 25 +++++++++++++----- toolchain/src/inst/encode.rs | 50 ++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/toolchain/src/inst.rs b/toolchain/src/inst.rs index ea3d2f4..cbb5292 100644 --- a/toolchain/src/inst.rs +++ b/toolchain/src/inst.rs @@ -2,6 +2,7 @@ pub mod decode; pub mod encode; #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] pub enum Op1 { Zero, Lsl1, @@ -14,6 +15,7 @@ pub enum Op1 { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] pub enum OpR { Add, Sub, @@ -26,6 +28,20 @@ pub enum OpR { } #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] +pub enum OpI3 { + Rol, + Lsl, + Lsr, + Asr, + Clr, + Set, + Tog, + Ext, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u8)] pub enum Data { D1, D2, @@ -50,10 +66,7 @@ pub enum AluI { Ior(u8), Xor(u8), Add(AddImm), - Rol(U3), - Lsl(U3), - Lsr(U3), - Asr(U3), + Compact(OpI3, U3), } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -71,8 +84,8 @@ pub enum Inst { Alu1(Op1), IsLt(Reg), AluR(OpR, Reg), - LdD(Data, Reg), - StD(Data, Reg), + LdD(Data, Reg, bool), + StD(Data, Reg, bool), AluI(AluI), BEzI(i8), JOfI(i8), diff --git a/toolchain/src/inst/encode.rs b/toolchain/src/inst/encode.rs index 085751d..ffa9614 100644 --- a/toolchain/src/inst/encode.rs +++ b/toolchain/src/inst/encode.rs @@ -1,5 +1,55 @@ +use super::{AluI, Data, Inst, Reg, Special, U3}; use std::io::{self, Write}; pub trait Encode { fn encode(&self, writer: &mut impl Write) -> io::Result<()>; } + +fn reg(Reg(U3(x)): Reg) -> u8 { + x +} + +fn sp(s: Special) -> u8 { + match s { + Special::Data(Data::D1) => 0b00, + Special::Data(Data::D2) => 0b01, + Special::Code => 0b10, + } +} + +impl Encode for Inst { + fn encode(&self, writer: &mut impl Write) -> io::Result<()> { + match *self { + Inst::Trap => writer.write(&[0x00])?, + Inst::JAbs => writer.write(&[0x04])?, + Inst::CAbs => writer.write(&[0x05])?, + Inst::JOff => writer.write(&[0x06])?, + Inst::COff => writer.write(&[0x07])?, + Inst::Swap(r) => writer.write(&[0x08 | reg(r)])?, + Inst::GetR(r) => writer.write(&[0x10 | reg(r)])?, + Inst::SetR(r) => writer.write(&[0x18 | reg(r)])?, + Inst::Get(s) => writer.write(&[0x20 | sp(s)])?, + Inst::Set(s) => writer.write(&[0x28 | sp(s)])?, + Inst::Alu1(op) => writer.write(&[0x30 | op as u8])?, + Inst::IsLt(r) => writer.write(&[0x38 | reg(r)])?, + Inst::AluR(op, r) => writer.write(&[0x40 | (op as u8) << 3 | reg(r)])?, + Inst::LdD(d, r, inc) => { + writer.write(&[0x80 | (d as u8) << 5 | (inc as u8) << 4 | reg(r)])? + } + Inst::StD(d, r, inc) => { + writer.write(&[0x88 | (d as u8) << 5 | (inc as u8) << 4 | reg(r)])? + } + Inst::AluI(alu) => match alu { + AluI::And(imm) => writer.write(&[0xf0, imm])?, + AluI::Ior(imm) => writer.write(&[0xf1, imm])?, + AluI::Xor(imm) => writer.write(&[0xf2, imm])?, + AluI::Add(imm) => writer.write(&[0xf3, imm.0 as u8])?, + AluI::Compact(op, imm) => writer.write(&[0xf3, 0x80 | (op as u8) << 3 | imm.0])?, + }, + Inst::BEzI(off) => writer.write(&[0xf4, off as u8])?, + Inst::JOfI(off) => writer.write(&[0xf6, off as u8])?, + Inst::COfI(off) => writer.write(&[0xf7, off as u8])?, + }; + Ok(()) + } +} -- 2.43.2