Implemented InstDisplay for pseudo instructions and directives.

Added a lifetime and string variant for `InstFmtArg`.
Added a lifetime to `InstDisplay`.
Added `InstFmtArg::write` to write an argument.
This commit is contained in:
Filipe Rodrigues 2021-04-26 14:55:46 +01:00
parent d0bd0d22b3
commit c066f3f2f8
25 changed files with 251 additions and 86 deletions

View File

@ -138,13 +138,13 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = impl Iterator<Item = InstFmtArg>;
impl<'a> InstDisplay<'a> for Inst {
type Args = impl Iterator<Item = InstFmtArg<'a>>;
type Mnemonic = impl fmt::Display;
#[auto_enums::auto_enum(Display)]
#[rustfmt::skip]
fn mnemonic<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic {
match self {
Inst::Alu (inst) => inst.mnemonic(ctx),
Inst::Cond (inst) => inst.mnemonic(ctx),
@ -161,7 +161,7 @@ impl InstDisplay for Inst {
#[auto_enums::auto_enum(Iterator)]
#[rustfmt::skip]
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
match self {
Inst::Alu (inst) => inst.args(ctx),
Inst::Cond (inst) => inst.args(ctx),

View File

@ -49,12 +49,12 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl Iterator<Item = InstFmtArg>;
type Args = impl Iterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic {
match self {
Inst::Imm(inst) => inst.mnemonic(ctx),
Inst::Reg(inst) => inst.mnemonic(ctx),
@ -62,7 +62,7 @@ impl InstDisplay for Inst {
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
match self {
Inst::Imm(inst) => inst.args(ctx).into_iter(),
Inst::Reg(inst) => inst.args(ctx).into_iter(),

View File

@ -161,17 +161,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl IntoIterator<Item = InstFmtArg>;
type Args = impl IntoIterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, lhs, kind } = self;
let value = kind.value();

View File

@ -161,17 +161,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl IntoIterator<Item = InstFmtArg>;
type Args = impl IntoIterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, lhs, rhs, kind } = self;
// If we're not `slt[u]` and if `$dst` and `$lhs` are the same,

View File

@ -238,11 +238,11 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = impl Iterator<Item = InstFmtArg>;
impl<'a> InstDisplay<'a> for Inst {
type Args = impl Iterator<Item = InstFmtArg<'a>>;
type Mnemonic = impl fmt::Display;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
/// Wrapper necessary for `impl Trait` to work without using `Ctx`.
fn wrapper(n: u32, kind: Kind) -> impl fmt::Display {
dcb_util::DisplayWrapper::new(move |f| match kind {
@ -268,7 +268,7 @@ impl InstDisplay for Inst {
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { kind, .. } = self;
match kind {
Kind::CopN { imm } => array::IntoIter::new([InstFmtArg::literal(imm)]),

View File

@ -190,12 +190,12 @@ impl Parsable for Inst {
/// `beq $zr, $zr, offset` => `b offset`
/// `beq $arg, $zr, offset` => `beqz $arg, offset`
/// `bne $arg, $zr, offset` => `bnez $arg, offset`
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl Iterator<Item = InstFmtArg>;
type Args = impl Iterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
match self.kind {
Kind::Equal(Register::Zr) => match self.arg {
Register::Zr => "b",
@ -215,7 +215,7 @@ impl InstDisplay for Inst {
#[auto_enums::auto_enum(Iterator)]
#[rustfmt::skip]
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
use InstFmtArg::Register as register;
let &Self { arg, offset, kind } = self;
let target = Self::target_of(offset, ctx.cur_pos());

View File

@ -49,12 +49,12 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl Iterator<Item = InstFmtArg>;
type Args = impl Iterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic {
match self {
Inst::Imm(inst) => inst.mnemonic(ctx),
Inst::Reg(inst) => inst.mnemonic(ctx),
@ -62,7 +62,7 @@ impl InstDisplay for Inst {
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
match self {
Inst::Imm(inst) => inst.args(ctx),
Inst::Reg(inst) => inst.args(ctx).into_iter(),

View File

@ -110,15 +110,15 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = array::IntoIter<InstFmtArg, 1>;
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 1>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
array::IntoIter::new([InstFmtArg::Target(Self::target_of(self.imm, ctx.cur_pos()))])
}
}

View File

@ -93,17 +93,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl IntoIterator<Item = InstFmtArg>;
type Args = impl IntoIterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { target, kind } = self;
match kind {

View File

@ -140,15 +140,15 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = array::IntoIter<InstFmtArg, 2>;
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { value, addr, offset, .. } = self;
array::IntoIter::new([InstFmtArg::Register(value), InstFmtArg::register_offset(addr, offset)])

View File

@ -62,15 +62,15 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = array::IntoIter<InstFmtArg, 2>;
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
"lui"
}
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, value } = self;
array::IntoIter::new([InstFmtArg::Register(dst), InstFmtArg::literal(value)])

View File

@ -206,17 +206,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl Iterator<Item = InstFmtArg>;
type Args = impl Iterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
Self::mnemonic(*self)
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
match *self {
Self::Mult { lhs, rhs, .. } => array::IntoIter::new([InstFmtArg::Register(lhs), InstFmtArg::Register(rhs)]),
Self::MoveFrom { dst: arg, .. } | Self::MoveTo { src: arg, .. } => array::IntoIter::new([InstFmtArg::Register(arg)]),

View File

@ -58,12 +58,12 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl Iterator<Item = InstFmtArg>;
type Args = impl Iterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic {
match self {
Inst::Imm(inst) => inst.mnemonic(ctx),
Inst::Reg(inst) => inst.mnemonic(ctx),
@ -71,7 +71,7 @@ impl InstDisplay for Inst {
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
match self {
Inst::Imm(inst) => inst.args(ctx).into_iter(),
Inst::Reg(inst) => inst.args(ctx).into_iter(),

View File

@ -128,17 +128,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl IntoIterator<Item = InstFmtArg>;
type Args = impl IntoIterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, lhs, rhs, .. } = self;
// If `$dst` and `$lhs` are the same, only print one of them

View File

@ -109,17 +109,17 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
impl<'a> InstDisplay<'a> for Inst {
type Mnemonic = &'static str;
type Args = impl IntoIterator<Item = InstFmtArg>;
type Args = impl IntoIterator<Item = InstFmtArg<'a>>;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
#[auto_enums::auto_enum(Iterator)]
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, lhs, rhs, .. } = self;
// If `$dst` and `$lhs` are the same, only print one of them

View File

@ -127,15 +127,15 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = array::IntoIter<InstFmtArg, 2>;
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { value, addr, offset, .. } = self;
array::IntoIter::new([InstFmtArg::Register(value), InstFmtArg::register_offset(addr, offset)])

View File

@ -103,15 +103,15 @@ impl Parsable for Inst {
}
}
impl InstDisplay for Inst {
type Args = array::IntoIter<InstFmtArg, 1>;
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 1>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Mnemonic {
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&self, _ctx: &Ctx) -> Self::Args {
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
array::IntoIter::new([InstFmtArg::literal(self.comment)])
}
}

View File

@ -1,11 +1,14 @@
//! Directives
// Imports
use super::{InstFmt, InstSize, InstTargetFmt};
use super::{DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, InstTargetFmt};
use crate::{DataType, Pos};
use ascii::{AsciiChar, AsciiStr};
use dcb_util::NextFromBytes;
use std::io::{self, Write};
use std::{
array,
io::{self, Write},
};
/// A directive
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@ -152,6 +155,30 @@ impl<'a> Directive<'a> {
}
}
impl<'a> InstDisplay<'a> for Directive<'a> {
type Args = array::IntoIter<InstFmtArg<'a>, 1>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
match self {
Directive::Dw(_) => "dw",
Directive::Dh(_) => "dh",
Directive::Db(_) => "db",
Directive::Ascii(_) => ".ascii",
}
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let arg = match *self {
Directive::Dw(value) => InstFmtArg::literal(value),
Directive::Dh(value) => InstFmtArg::literal(value),
Directive::Db(value) => InstFmtArg::literal(value),
Directive::Ascii(s) => InstFmtArg::String(s.as_str()),
};
array::IntoIter::new([arg])
}
}
impl<'a> InstSize for Directive<'a> {
fn size(&self) -> usize {
match self {

View File

@ -5,32 +5,37 @@
// Imports
use super::InstTarget;
use crate::{inst::Register, Pos};
use dcb_util::SignedHex;
use std::fmt;
/// Instruction display
pub trait InstDisplay {
// TODO: Move `'a` to gat once they are implemented
pub trait InstDisplay<'a> {
/// Mnemonic type
type Mnemonic: fmt::Display;
/// Args type
type Args: IntoIterator<Item = InstFmtArg>;
type Args: IntoIterator<Item = InstFmtArg<'a>>;
/// Returns this instruction's mnemonic
fn mnemonic<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Mnemonic;
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic;
/// Returns all arguments of this instruction
fn args<Ctx: DisplayCtx>(&self, ctx: &Ctx) -> Self::Args;
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args;
}
/// Display context
pub trait DisplayCtx {
/// Current position
fn cur_pos(&self) -> Pos;
/// Returns any label at `pos`, possibly with an offset
fn pos_label(&self, pos: Pos) -> Option<(&str, i64)>;
}
/// An formattable argument
#[derive(PartialEq, Clone, Debug)]
pub enum InstFmtArg {
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum InstFmtArg<'a> {
/// Register
Register(Register),
@ -48,9 +53,12 @@ pub enum InstFmtArg {
/// Target
Target(Pos),
/// String
String(&'a str),
}
impl InstFmtArg {
impl<'a> InstFmtArg<'a> {
/// Creates a `Literal` variant
#[must_use]
pub fn literal(value: impl Into<i64>) -> Self {
@ -65,6 +73,23 @@ impl InstFmtArg {
offset: offset.into(),
}
}
/// Writes this argument
pub fn write<Ctx: DisplayCtx>(&self, f: &mut fmt::Formatter, ctx: &Ctx) -> Result<(), fmt::Error> {
match *self {
// Register offsets with 0 offset are formatted like normal registers
InstFmtArg::Register(register) | InstFmtArg::RegisterOffset { register, offset: 0 } => write!(f, "{register}"),
InstFmtArg::RegisterOffset { register, offset } => write!(f, "{}({register})", SignedHex(offset)),
// Note: Literals do not go through label lookup
InstFmtArg::Literal(value) => write!(f, "{}", SignedHex(value)),
InstFmtArg::Target(pos) => match ctx.pos_label(pos) {
Some((label, 0)) => write!(f, "{label}"),
Some((label, offset)) => write!(f, "{label}+{}", SignedHex(offset)),
None => write!(f, "{pos}"),
},
InstFmtArg::String(s) => write!(f, "{}", s.escape_debug()),
}
}
}

View File

@ -12,7 +12,8 @@ pub mod nop;
pub mod store;
// Imports
use super::{basic, InstFmt, InstSize};
use super::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize};
use core::fmt;
/// A pseudo instruction
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@ -60,6 +61,35 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = impl Iterator<Item = InstFmtArg<'a>>;
type Mnemonic = impl fmt::Display;
#[auto_enums::auto_enum(Display)]
#[rustfmt::skip]
fn mnemonic<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Mnemonic {
match self {
Inst::LoadImm(inst) => inst.mnemonic(ctx),
Inst::Nop (inst) => inst.mnemonic(ctx),
Inst::MoveReg(inst) => inst.mnemonic(ctx),
Inst::Load (inst) => inst.mnemonic(ctx),
Inst::Store (inst) => inst.mnemonic(ctx),
}
}
#[auto_enums::auto_enum(Iterator)]
#[rustfmt::skip]
fn args<Ctx: DisplayCtx>(&'a self, ctx: &Ctx) -> Self::Args {
match self {
Inst::LoadImm(inst) => inst.args(ctx),
Inst::Nop (inst) => inst.args(ctx),
Inst::MoveReg(inst) => inst.args(ctx),
Inst::Load (inst) => inst.args(ctx),
Inst::Store (inst) => inst.args(ctx),
}
}
}
impl InstSize for Inst {
fn size(&self) -> usize {
match self {

View File

@ -3,10 +3,11 @@
// Imports
use super::{Decodable, Encodable};
use crate::{
inst::{basic, InstSize, InstTarget, InstTargetFmt, Register},
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, InstTarget, InstTargetFmt, Register},
Pos,
};
use int_conv::{Join, SignExtended, Signed, Split};
use std::array;
/// Load pseudo instructions
///
@ -71,6 +72,21 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { value, target, .. } = self;
array::IntoIter::new([InstFmtArg::Register(value), InstFmtArg::Target(target)])
}
}
impl InstSize for Inst {
fn size(&self) -> usize {
8

View File

@ -3,12 +3,12 @@
// Imports
use super::{Decodable, Encodable};
use crate::{
inst::{basic, InstFmt, InstSize, InstTargetFmt, Register},
inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, InstTargetFmt, Register},
Pos,
};
use dcb_util::SignedHex;
use int_conv::{Join, SignExtended, Signed, Split};
use std::convert::TryInto;
use std::{array, convert::TryInto};
/// Immediate kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@ -153,6 +153,27 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, kind } = self;
let arg = match kind {
Kind::Address(pos) => InstFmtArg::Target(pos),
Kind::Word(value) => InstFmtArg::literal(value),
Kind::HalfWordUnsigned(value) => InstFmtArg::literal(value),
Kind::HalfWordSigned(value) => InstFmtArg::literal(value),
};
array::IntoIter::new([InstFmtArg::Register(dst), arg])
}
}
impl InstSize for Inst {
fn size(&self) -> usize {
match self.kind {

View File

@ -2,8 +2,8 @@
// Imports
use super::{Decodable, Encodable};
use crate::inst::{basic, InstFmt, InstSize, Register};
use std::convert::TryInto;
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, Register};
use std::{array, convert::TryInto};
/// Move register instruction
///
@ -48,6 +48,21 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
"move"
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { dst, src } = self;
array::IntoIter::new([InstFmtArg::Register(dst), InstFmtArg::Register(src)])
}
}
impl InstSize for Inst {
fn size(&self) -> usize {
4

View File

@ -2,7 +2,8 @@
// Imports
use super::{Decodable, Encodable};
use crate::inst::{basic, InstFmt, InstSize, Register};
use crate::inst::{basic, DisplayCtx, InstDisplay, InstFmt, InstFmtArg, InstSize, Register};
use std::{array, convert::TryFrom};
/// No-op
///
@ -35,7 +36,6 @@ impl Decodable for Inst {
}
}
impl Encodable for Inst {
type Iterator = impl Iterator<Item = basic::Inst>;
@ -44,6 +44,21 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 1>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
"nop"
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { len } = self;
let len = i64::try_from(len).expect("Too many nops");
array::IntoIter::new([InstFmtArg::Literal(len)])
}
}
impl InstSize for Inst {
fn size(&self) -> usize {

View File

@ -3,10 +3,11 @@
// Imports
use super::{Decodable, Encodable};
use crate::{
inst::{basic, InstSize, InstTarget, InstTargetFmt, Register},
inst::{basic, DisplayCtx, InstDisplay, InstFmtArg, InstSize, InstTarget, InstTargetFmt, Register},
Pos,
};
use int_conv::{Join, SignExtended, Signed, Split};
use std::array;
/// Store pseudo instructions
///
@ -70,6 +71,21 @@ impl Encodable for Inst {
}
}
impl<'a> InstDisplay<'a> for Inst {
type Args = array::IntoIter<InstFmtArg<'a>, 2>;
type Mnemonic = &'static str;
fn mnemonic<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Mnemonic {
self.kind.mnemonic()
}
fn args<Ctx: DisplayCtx>(&'a self, _ctx: &Ctx) -> Self::Args {
let &Self { value, target, .. } = self;
array::IntoIter::new([InstFmtArg::Register(value), InstFmtArg::Target(target)])
}
}
impl InstSize for Inst {
fn size(&self) -> usize {
8