mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-04 08:23:13 +00:00
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:
parent
d0bd0d22b3
commit
c066f3f2f8
@ -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),
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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();
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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)]),
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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()))])
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)])
|
||||
|
||||
@ -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)])
|
||||
|
||||
@ -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)]),
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)])
|
||||
|
||||
@ -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)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user