Removed all Raw from inst::basic. Instructions are now decoded directly by their raw form.

`slti` and `sltiu` cannot be shortened anymore.
This commit is contained in:
Filipe Rodrigues 2021-04-25 09:24:17 +01:00
parent e6f09fa31c
commit bb7e0d40af
17 changed files with 317 additions and 523 deletions

View File

@ -82,7 +82,7 @@ impl<'a> Inst<'a> {
.array_chunks::<4>()
.copied()
.map(u32::from_ne_bytes)
.map_while(|word| basic::Raw::from_u32(word).and_then(basic::Inst::decode))
.map_while(basic::Inst::decode)
.fuse();
// Try to decode a pseudo-instruction
@ -112,11 +112,11 @@ impl<'a> Inst<'a> {
pub fn write(&self, f: &mut impl Write) -> Result<(), io::Error> {
match self {
Inst::Basic(inst) => {
f.write_all(&inst.encode().as_u32().to_le_bytes())?;
f.write_all(&inst.encode().to_le_bytes())?;
},
Inst::Pseudo(inst) => {
for inst in inst.encode() {
f.write_all(&inst.encode().as_u32().to_le_bytes())?;
f.write_all(&inst.encode().to_le_bytes())?;
}
},
Inst::Directive(directive) => directive.write(f)?,

View File

@ -20,91 +20,6 @@ pub mod sys;
use super::{InstSize, Register};
use crate::inst::InstFmt;
/// Raw instruction
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Raw {
/// Alu
Alu(alu::Raw),
/// Condition
Cond(cond::Raw),
/// Jump
Jmp(jmp::Raw),
/// Load
Load(load::Raw),
/// Load upper immediate
Lui(lui::Raw),
/// Multiplication
Mult(mult::Raw),
/// Shift
Shift(shift::Raw),
/// Store
Store(store::Raw),
/// Syscall
Sys(sys::Raw),
/// Co-processor
Co(u32),
}
impl Raw {
/// Constructs a raw instruction from a `u32`.
#[must_use]
#[bitmatch::bitmatch]
#[allow(clippy::many_single_char_names)] // `bitmatch` can only output single character names.
pub fn from_u32(raw: u32) -> Option<Self> {
#[rustfmt::skip]
let raw = #[bitmatch] match raw {
"000000_?????_ttttt_ddddd_iiiii_0000ff" => Self::Shift(shift::Raw::Imm(shift::imm::Raw { t, d, i, f })),
"000000_sssss_ttttt_ddddd_?????_0001ff" => Self::Shift(shift::Raw::Reg(shift::reg::Raw { s, t, d, f })),
"000000_sssss_?????_ddddd_?????_00100f" => Self::Jmp (jmp ::Raw::Reg(jmp ::reg::Raw { s, d, f })),
"000000_ccccc_ccccc_ccccc_ccccc_00110f" => Self::Sys ( sys :: Raw { c, f } ),
"000000_sssss_ttttt_ddddd_?????_01ffff" => Self::Mult ( mult :: Raw { s, t, d, f } ),
"000000_sssss_ttttt_ddddd_?????_10ffff" => Self::Alu (alu ::Raw::Reg(alu ::reg::Raw { s, t, d, f })),
"00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => Self::Jmp (jmp ::Raw::Imm(jmp ::imm::Raw { p, i })),
"000ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Cond ( cond :: Raw { p, s, t, i } ),
"001111_?????_ttttt_iiiii_iiiii_iiiiii" => Self::Lui ( lui :: Raw { t, i } ),
"001ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Alu (alu ::Raw::Imm(alu ::imm::Raw { p, s, t, i })),
"100ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Load ( load :: Raw { p, s, t, i } ),
"101ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Store( store:: Raw { p, s, t, i } ),
"?1????_?????_?????_?????_?????_??????" => Self::Co (raw),
_ => return None,
};
Some(raw)
}
/// Encodes this raw as a `u32`
#[must_use]
#[bitmatch::bitmatch]
#[rustfmt::skip]
pub const fn as_u32(&self) -> u32 {
match *self {
Self::Shift(shift::Raw::Imm(shift::imm::Raw { t, d, i, f })) => bitpack!("000000_?????_ttttt_ddddd_iiiii_0000ff"),
Self::Shift(shift::Raw::Reg(shift::reg::Raw { s, t, d, f })) => bitpack!("000000_sssss_ttttt_ddddd_?????_0001ff"),
Self::Jmp (jmp ::Raw::Reg(jmp ::reg::Raw { s, d, f })) => bitpack!("000000_sssss_?????_ddddd_?????_00100f"),
Self::Sys ( sys :: Raw { c, f } ) => bitpack!("000000_ccccc_ccccc_ccccc_ccccc_00110f"),
Self::Mult ( mult :: Raw { s, t, d, f } ) => bitpack!("000000_sssss_ttttt_ddddd_?????_01ffff"),
Self::Alu (alu ::Raw::Reg(alu ::reg::Raw { s, t, d, f })) => bitpack!("000000_sssss_ttttt_ddddd_?????_10ffff"),
Self::Jmp (jmp ::Raw::Imm(jmp ::imm::Raw { p, i })) => bitpack!("00001p_iiiii_iiiii_iiiii_iiiii_iiiiii"),
Self::Cond ( cond :: Raw { p, s, t, i } ) => bitpack!("000ppp_sssss_ttttt_iiiii_iiiii_iiiiii"),
Self::Lui ( lui :: Raw { t, i } ) => bitpack!("001111_?????_ttttt_iiiii_iiiii_iiiiii"),
Self::Alu (alu ::Raw::Imm(alu ::imm::Raw { p, s, t, i })) => bitpack!("001ppp_sssss_ttttt_iiiii_iiiii_iiiiii"),
Self::Load ( load :: Raw { p, s, t, i } ) => bitpack!("100ppp_sssss_ttttt_iiiii_iiiii_iiiiii"),
Self::Store( store:: Raw { p, s, t, i } ) => bitpack!("101ppp_sssss_ttttt_iiiii_iiiii_iiiiii"),
Self::Co (raw) => raw,
}
}
}
/// All basic instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::TryInto)]
@ -142,25 +57,21 @@ pub enum Inst {
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[rustfmt::skip]
fn decode(raw: Self::Raw) -> Option<Self> {
#[rustfmt::skip]
let inst =
match raw {
Raw::Alu (raw) => Self::Alu (alu ::Inst::decode(raw)?),
Raw::Cond (raw) => Self::Cond (cond ::Inst::decode(raw)?),
Raw::Jmp (raw) => Self::Jmp (jmp ::Inst::decode(raw)?),
Raw::Load (raw) => Self::Load (load ::Inst::decode(raw)?),
Raw::Lui (raw) => Self::Lui (lui ::Inst::decode(raw)?),
Raw::Mult (raw) => Self::Mult (mult ::Inst::decode(raw)?),
Raw::Shift(raw) => Self::Shift(shift::Inst::decode(raw)?),
Raw::Store(raw) => Self::Store(store::Inst::decode(raw)?),
Raw::Sys (raw) => Self::Sys (sys ::Inst::decode(raw)?),
Raw::Co (raw) => Self::Co (co ::Inst::decode(raw)?),
};
Some(inst)
None
.or_else(|| alu ::Inst::decode(raw).map(Self::Alu ))
.or_else(|| cond ::Inst::decode(raw).map(Self::Cond ))
.or_else(|| jmp ::Inst::decode(raw).map(Self::Jmp ))
.or_else(|| load ::Inst::decode(raw).map(Self::Load ))
.or_else(|| lui ::Inst::decode(raw).map(Self::Lui ))
.or_else(|| mult ::Inst::decode(raw).map(Self::Mult ))
.or_else(|| shift::Inst::decode(raw).map(Self::Shift))
.or_else(|| store::Inst::decode(raw).map(Self::Store))
.or_else(|| sys ::Inst::decode(raw).map(Self::Sys ))
.or_else(|| co ::Inst::decode(raw).map(Self::Co ))
}
}
@ -168,33 +79,34 @@ impl Encodable for Inst {
#[rustfmt::skip]
fn encode(&self) -> Self::Raw {
match self {
Self::Alu (inst) => Raw::Alu (inst.encode()),
Self::Cond (inst) => Raw::Cond (inst.encode()),
Self::Jmp (inst) => Raw::Jmp (inst.encode()),
Self::Load (inst) => Raw::Load (inst.encode()),
Self::Lui (inst) => Raw::Lui (inst.encode()),
Self::Mult (inst) => Raw::Mult (inst.encode()),
Self::Shift(inst) => Raw::Shift(inst.encode()),
Self::Store(inst) => Raw::Store(inst.encode()),
Self::Sys (inst) => Raw::Sys (inst.encode()),
Self::Co (inst) => Raw::Co (inst.encode()),
Self::Alu (inst) => inst.encode(),
Self::Cond (inst) => inst.encode(),
Self::Jmp (inst) => inst.encode(),
Self::Load (inst) => inst.encode(),
Self::Lui (inst) => inst.encode(),
Self::Mult (inst) => inst.encode(),
Self::Shift(inst) => inst.encode(),
Self::Store(inst) => inst.encode(),
Self::Sys (inst) => inst.encode(),
Self::Co (inst) => inst.encode(),
}
}
}
impl ModifiesReg for Inst {
#[rustfmt::skip]
fn modifies_reg(&self, reg: Register) -> bool {
match self {
Inst::Alu(inst) => inst.modifies_reg(reg),
Inst::Cond(inst) => inst.modifies_reg(reg),
Inst::Jmp(inst) => inst.modifies_reg(reg),
Inst::Load(inst) => inst.modifies_reg(reg),
Inst::Lui(inst) => inst.modifies_reg(reg),
Inst::Mult(inst) => inst.modifies_reg(reg),
Inst::Alu (inst) => inst.modifies_reg(reg),
Inst::Cond (inst) => inst.modifies_reg(reg),
Inst::Jmp (inst) => inst.modifies_reg(reg),
Inst::Load (inst) => inst.modifies_reg(reg),
Inst::Lui (inst) => inst.modifies_reg(reg),
Inst::Mult (inst) => inst.modifies_reg(reg),
Inst::Shift(inst) => inst.modifies_reg(reg),
Inst::Store(inst) => inst.modifies_reg(reg),
Inst::Sys(inst) => inst.modifies_reg(reg),
Inst::Co(inst) => inst.modifies_reg(reg),
Inst::Sys (inst) => inst.modifies_reg(reg),
Inst::Co (inst) => inst.modifies_reg(reg),
}
}
}

View File

@ -11,17 +11,6 @@ use crate::inst::{
InstFmt,
};
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::From)]
pub enum Raw {
/// Immediate
Imm(imm::Raw),
/// Register
Reg(reg::Raw),
}
/// Alu register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::TryInto)]
@ -34,22 +23,17 @@ pub enum Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
fn decode(raw: Self::Raw) -> Option<Self> {
match raw {
Raw::Imm(raw) => Some(Self::Imm(imm::Inst::decode(raw)?)),
Raw::Reg(raw) => Some(Self::Reg(reg::Inst::decode(raw)?)),
}
None.or_else(|| imm::Inst::decode(raw).map(Self::Imm))
.or_else(|| reg::Inst::decode(raw).map(Self::Reg))
}
}
impl Encodable for Inst {
fn encode(&self) -> Self::Raw {
match self {
Self::Imm(inst) => Raw::Imm(inst.encode()),
Self::Reg(inst) => Raw::Reg(inst.encode()),
}
todo!();
}
}

View File

@ -9,7 +9,7 @@ use dcb_util::SignedHex;
use int_conv::{Signed, Truncated, ZeroExtended};
use std::fmt;
/// Alu immediate instruction kind
/// Instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Kind {
/// Add signed with overflow trap
@ -61,22 +61,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Opcode (lower 3 bits)
pub p: u32,
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Immediate
pub i: u32,
}
/// Alu immediate instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -91,45 +75,50 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
#[rustfmt::skip]
let kind = match raw.p {
0x0 => Kind::Add (raw.i.truncated::<u16>().as_signed()),
0x1 => Kind::AddUnsigned (raw.i.truncated::<u16>().as_signed()),
0x2 => Kind::SetLessThan (raw.i.truncated::<u16>().as_signed()),
0x3 => Kind::SetLessThanUnsigned(raw.i.truncated::<u16>()),
0x4 => Kind::And (raw.i.truncated::<u16>()),
0x5 => Kind::Or (raw.i.truncated::<u16>()),
0x6 => Kind::Xor (raw.i.truncated::<u16>()),
let [p, s, t, i] = #[bitmatch]
match raw {
"001ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => [p, s, t, i],
_ => return None,
};
Some(Self {
dst: Register::new(raw.t)?,
lhs: Register::new(raw.s)?,
kind,
dst: Register::new(t)?,
lhs: Register::new(s)?,
kind: match p {
0x0 => Kind::Add(i.truncated::<u16>().as_signed()),
0x1 => Kind::AddUnsigned(i.truncated::<u16>().as_signed()),
0x2 => Kind::SetLessThan(i.truncated::<u16>().as_signed()),
0x3 => Kind::SetLessThanUnsigned(i.truncated::<u16>()),
0x4 => Kind::And(i.truncated::<u16>()),
0x5 => Kind::Or(i.truncated::<u16>()),
0x6 => Kind::Xor(i.truncated::<u16>()),
_ => return None,
},
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
#[rustfmt::skip]
let (p, i) = match self.kind {
let (p, i): (u32, u32) = match self.kind {
Kind::Add (rhs) => (0x0, rhs.as_unsigned().zero_extended::<u32>()),
Kind::AddUnsigned (rhs) => (0x1, rhs.as_unsigned().zero_extended::<u32>()),
Kind::SetLessThan (rhs) => (0x2, rhs.as_unsigned().zero_extended::<u32>()),
Kind::SetLessThanUnsigned(rhs) => (0x3, rhs.as_unsigned().zero_extended::<u32>()),
Kind::And (rhs) => (0x4, rhs.as_unsigned().zero_extended::<u32>()),
Kind::Or (rhs) => (0x5, rhs.as_unsigned().zero_extended::<u32>()),
Kind::Xor (rhs) => (0x6, rhs.as_unsigned().zero_extended::<u32>()),
Kind::SetLessThanUnsigned(rhs) => (0x3, rhs .zero_extended::<u32>()),
Kind::And (rhs) => (0x4, rhs .zero_extended::<u32>()),
Kind::Or (rhs) => (0x5, rhs .zero_extended::<u32>()),
Kind::Xor (rhs) => (0x6, rhs .zero_extended::<u32>()),
};
let s = self.lhs.idx();
let t = self.dst.idx();
let s = self.lhs.idx();
Raw { p, s, t, i }
bitpack!("001ppp_sssss_ttttt_iiiii_iiiii_iiiiii")
}
}
@ -139,8 +128,9 @@ impl InstFmt for Inst {
let mnemonic = kind.mnemonic();
let value = kind.value_fmt();
// If `$dst` and `$lhs` are the same, only print one of them
match dst == lhs {
// If we're not `slti[u]` and if `$dst` and `$lhs` are the same,
// only print one of them
match !matches!(kind, Kind::SetLessThan(_) | Kind::SetLessThanUnsigned(_)) && dst == lhs {
true => write!(f, "{mnemonic} {dst}, {value}"),
false => write!(f, "{mnemonic} {dst}, {lhs}, {value}"),
}

View File

@ -1,7 +1,10 @@
//! Alu register instructions
// Imports
use crate::inst::{InstFmt, Register, basic::{Decodable, Encodable, ModifiesReg}};
use crate::inst::{
basic::{Decodable, Encodable, ModifiesReg},
InstFmt, Register,
};
/// Alu register instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@ -56,22 +59,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Rd
pub d: u32,
/// Func (lower 4 bits)
pub f: u32,
}
/// Alu register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -89,43 +76,50 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
0x0 => Kind::Add,
0x1 => Kind::AddUnsigned,
0x2 => Kind::Sub,
0x3 => Kind::SubUnsigned,
0x4 => Kind::And,
0x5 => Kind::Or,
0x6 => Kind::Xor,
0x7 => Kind::Nor,
0xa => Kind::SetLessThan,
0xb => Kind::SetLessThanUnsigned,
let [s, t, d, f] = #[bitmatch]
match raw {
"000000_sssss_ttttt_ddddd_?????_10ffff" => [s, t, d, f],
_ => return None,
};
Some(Self {
dst: Register::new(raw.d)?,
lhs: Register::new(raw.s)?,
rhs: Register::new(raw.t)?,
kind,
dst: Register::new(d)?,
lhs: Register::new(s)?,
rhs: Register::new(t)?,
kind: match f {
0x0 => Kind::Add,
0x1 => Kind::AddUnsigned,
0x2 => Kind::Sub,
0x3 => Kind::SubUnsigned,
0x4 => Kind::And,
0x5 => Kind::Or,
0x6 => Kind::Xor,
0x7 => Kind::Nor,
0xa => Kind::SetLessThan,
0xb => Kind::SetLessThanUnsigned,
_ => return None,
},
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let f = match self.kind {
Kind::Add => 0x0,
Kind::AddUnsigned => 0x1,
Kind::Sub => 0x2,
Kind::SubUnsigned => 0x3,
Kind::And => 0x4,
Kind::Or => 0x5,
Kind::Xor => 0x6,
Kind::Nor => 0x7,
Kind::SetLessThan => 0xa,
#[rustfmt::skip]
let f: u32 = match self.kind {
Kind::Add => 0x0,
Kind::AddUnsigned => 0x1,
Kind::Sub => 0x2,
Kind::SubUnsigned => 0x3,
Kind::And => 0x4,
Kind::Or => 0x5,
Kind::Xor => 0x6,
Kind::Nor => 0x7,
Kind::SetLessThan => 0xa,
Kind::SetLessThanUnsigned => 0xb,
};
@ -133,7 +127,7 @@ impl Encodable for Inst {
let s = self.lhs.idx();
let t = self.rhs.idx();
Raw { s, t, d, f }
bitpack!("000000_sssss_ttttt_ddddd_?????_10ffff")
}
}
@ -151,7 +145,7 @@ impl InstFmt for Inst {
}
impl ModifiesReg for Inst {
fn modifies_reg(&self, reg: Register) -> bool {
self.dst == reg
}
}
fn modifies_reg(&self, reg: Register) -> bool {
self.dst == reg
}
}

View File

@ -12,23 +12,7 @@ use crate::{
use int_conv::{SignExtended, Signed, Truncated, ZeroExtended};
use std::fmt;
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Opcode (lower 3 bits)
pub p: u32,
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Immediate
pub i: u32,
}
/// Condition kind
/// Instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Kind {
/// Equal
@ -78,36 +62,42 @@ impl Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.p {
0x1 => match raw.t {
0b00000 => Kind::LessThanZero,
0b00001 => Kind::GreaterOrEqualZero,
0b10000 => Kind::LessThanZeroLink,
0b10001 => Kind::GreaterOrEqualZeroLink,
_ => return None,
},
0x4 => Kind::Equal(Register::new(raw.t)?),
0x5 => Kind::NotEqual(Register::new(raw.t)?),
0x6 => Kind::LessOrEqualZero,
0x7 => Kind::GreaterThanZero,
let [p, s, t, i] = #[bitmatch]
match raw {
"000ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => [p, s, t, i],
_ => return None,
};
Some(Self {
arg: Register::new(raw.s)?,
offset: raw.i.truncated::<u16>().as_signed(),
kind,
arg: Register::new(s)?,
offset: i.truncated::<u16>().as_signed(),
kind: match p {
0x1 => match t {
0b00000 => Kind::LessThanZero,
0b00001 => Kind::GreaterOrEqualZero,
0b10000 => Kind::LessThanZeroLink,
0b10001 => Kind::GreaterOrEqualZeroLink,
_ => return None,
},
0x4 => Kind::Equal(Register::new(t)?),
0x5 => Kind::NotEqual(Register::new(t)?),
0x6 => Kind::LessOrEqualZero,
0x7 => Kind::GreaterThanZero,
_ => return None,
},
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
#[rustfmt::skip]
let (p, t) = match self.kind {
let (p, t): (u32, u32) = match self.kind {
Kind::Equal(reg) => (0x4, reg.idx()),
Kind::NotEqual(reg) => (0x5, reg.idx()),
Kind::LessOrEqualZero => (0x6, 0),
@ -119,9 +109,9 @@ impl Encodable for Inst {
};
let s = self.arg.idx();
let i = self.offset.as_unsigned().zero_extended();
let i: u32 = self.offset.as_unsigned().zero_extended();
Raw { p, s, t, i }
bitpack!("000ppp_sssss_ttttt_iiiii_iiiii_iiiiii")
}
}

View File

@ -11,17 +11,6 @@ use crate::inst::{
InstFmt, Register,
};
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::From)]
pub enum Raw {
/// Immediate
Imm(imm::Raw),
/// Register
Reg(reg::Raw),
}
/// Jmp register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::TryInto)]
@ -34,21 +23,19 @@ pub enum Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
fn decode(raw: Self::Raw) -> Option<Self> {
match raw {
Raw::Imm(raw) => Some(Self::Imm(imm::Inst::decode(raw)?)),
Raw::Reg(raw) => Some(Self::Reg(reg::Inst::decode(raw)?)),
}
None.or_else(|| imm::Inst::decode(raw).map(Self::Imm))
.or_else(|| reg::Inst::decode(raw).map(Self::Reg))
}
}
impl Encodable for Inst {
fn encode(&self) -> Self::Raw {
match self {
Self::Imm(inst) => Raw::Imm(inst.encode()),
Self::Reg(inst) => Raw::Reg(inst.encode()),
Self::Imm(inst) => inst.encode(),
Self::Reg(inst) => inst.encode(),
}
}
}

View File

@ -30,16 +30,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Opcode (lower bit)
pub p: u32,
/// Immediate
pub i: u32,
}
/// Jmp register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -59,28 +49,36 @@ impl Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.p {
0 => Kind::Jump,
1 => Kind::JumpLink,
let [p, i] = #[bitmatch]
match raw {
"00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => [p, i],
_ => return None,
};
Some(Self { imm: raw.i, kind })
let kind = match p {
0 => Kind::Jump,
1 => Kind::JumpLink,
_ => unreachable!(),
};
Some(Self { imm: i, kind })
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let p = match self.kind {
let p: u32 = match self.kind {
Kind::Jump => 0,
Kind::JumpLink => 1,
};
let i = self.imm;
Raw { p, i }
bitpack!("00001p_iiiii_iiiii_iiiii_iiiii_iiiiii")
}
}

View File

@ -27,19 +27,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rs
pub s: u32,
/// Rd
pub d: u32,
/// Func (lower bit)
pub f: u32,
}
/// Jmp register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -51,29 +38,37 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
0 => Kind::Jump,
1 => Kind::JumpLink(Register::new(raw.d)?),
let [s, d, f] = #[bitmatch]
match raw {
"000000_sssss_?????_ddddd_?????_00100f" => [s, d, f],
_ => return None,
};
let target = Register::new(raw.s)?;
let kind = match f {
0 => Kind::Jump,
1 => Kind::JumpLink(Register::new(d)?),
_ => return None,
};
let target = Register::new(s)?;
Some(Self { target, kind })
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let (f, d) = match self.kind {
let (f, d): (u32, u32) = match self.kind {
Kind::Jump => (0, 0),
Kind::JumpLink(reg) => (1, reg.idx()),
};
let s = self.target.idx();
Raw { s, d, f }
bitpack!("000000_sssss_?????_ddddd_?????_00100f")
}
}

View File

@ -9,7 +9,7 @@ use crate::inst::{
use dcb_util::SignedHex;
use int_conv::{Signed, Truncated, ZeroExtended};
/// Load instruction kind
/// Instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Kind {
/// Byte, `i8`
@ -35,7 +35,7 @@ pub enum Kind {
}
impl Kind {
/// Returns the mnemonic for this load kind
/// Returns the mnemonic for this kind
#[must_use]
pub const fn mnemonic(self) -> &'static str {
match self {
@ -50,22 +50,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Opcode (lower 3 bits)
pub p: u32,
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Immediate
pub i: u32,
}
/// Load instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -83,32 +67,38 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.p {
0x0 => Kind::Byte,
0x1 => Kind::HalfWord,
0x2 => Kind::WordLeft,
0x3 => Kind::Word,
0x4 => Kind::ByteUnsigned,
0x5 => Kind::HalfWordUnsigned,
0x6 => Kind::WordRight,
let [p, s, t, i] = #[bitmatch]
match raw {
"100ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => [p, s, t, i],
_ => return None,
};
Some(Self {
value: Register::new(raw.t)?,
addr: Register::new(raw.s)?,
offset: raw.i.truncated::<u16>().as_signed(),
kind,
value: Register::new(t)?,
addr: Register::new(s)?,
offset: i.truncated::<u16>().as_signed(),
kind: match p {
0x0 => Kind::Byte,
0x1 => Kind::HalfWord,
0x2 => Kind::WordLeft,
0x3 => Kind::Word,
0x4 => Kind::ByteUnsigned,
0x5 => Kind::HalfWordUnsigned,
0x6 => Kind::WordRight,
_ => return None,
},
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let p = match self.kind {
let p: u32 = match self.kind {
Kind::Byte => 0x0,
Kind::HalfWord => 0x1,
Kind::WordLeft => 0x2,
@ -121,7 +111,7 @@ impl Encodable for Inst {
let s = self.addr.idx();
let i = self.offset.as_unsigned().zero_extended::<u32>();
Raw { p, s, t, i }
bitpack!("100ppp_sssss_ttttt_iiiii_iiiii_iiiiii")
}
}

View File

@ -8,16 +8,6 @@ use crate::inst::{
};
use int_conv::{Truncated, ZeroExtended};
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rt
pub t: u32,
/// Immediate
pub i: u32,
}
/// Load instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -29,21 +19,29 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let [t, i] = #[bitmatch]
match raw {
"001111_?????_ttttt_iiiii_iiiii_iiiiii" => [t, i],
_ => return None,
};
Some(Self {
dst: Register::new(raw.t)?,
value: raw.i.truncated::<u16>(),
dst: Register::new(t)?,
value: i.truncated::<u16>(),
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
Raw {
t: self.dst.idx(),
i: self.value.zero_extended::<u32>(),
}
let t = self.dst.idx();
let i = self.value.zero_extended::<u32>();
bitpack!("001111_?????_ttttt_iiiii_iiiii_iiiiii")
}
}

View File

@ -37,22 +37,6 @@ pub enum MultReg {
Hi,
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Rd
pub d: u32,
/// Func (bottom 4 bits)
pub f: u32,
}
/// Multiplication instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Inst {
@ -115,24 +99,30 @@ impl Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[rustfmt::skip]
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
Some(match raw.f {
let [s, t, d, f] = #[bitmatch] match raw {
"000000_sssss_ttttt_ddddd_?????_01ffff" => [s, t, d, f],
_ => return None,
};
Some(match f {
// 00x0
0x0 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Hi },
0x2 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Lo },
0x0 => Self::MoveFrom { dst: Register::new(d)?, src: MultReg::Hi },
0x2 => Self::MoveFrom { dst: Register::new(d)?, src: MultReg::Lo },
// 00x1
0x1 => Self::MoveTo { src: Register::new(raw.s)?, dst: MultReg::Hi },
0x3 => Self::MoveTo { src: Register::new(raw.s)?, dst: MultReg::Lo },
0x1 => Self::MoveTo { src: Register::new(s)?, dst: MultReg::Hi },
0x3 => Self::MoveTo { src: Register::new(s)?, dst: MultReg::Lo },
// 10xx
0x8 => Self::Mult { kind: MultKind::Mult, mode: MultMode:: Signed, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
0x9 => Self::Mult { kind: MultKind::Mult, mode: MultMode::Unsigned, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
0xa => Self::Mult { kind: MultKind::Div , mode: MultMode:: Signed, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
0xb => Self::Mult { kind: MultKind::Div , mode: MultMode::Unsigned, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
0x8 => Self::Mult { kind: MultKind::Mult, mode: MultMode:: Signed, lhs: Register::new(s)?, rhs: Register::new(t)? },
0x9 => Self::Mult { kind: MultKind::Mult, mode: MultMode::Unsigned, lhs: Register::new(s)?, rhs: Register::new(t)? },
0xa => Self::Mult { kind: MultKind::Div , mode: MultMode:: Signed, lhs: Register::new(s)?, rhs: Register::new(t)? },
0xb => Self::Mult { kind: MultKind::Div , mode: MultMode::Unsigned, lhs: Register::new(s)?, rhs: Register::new(t)? },
_ => return None,
})
@ -140,39 +130,41 @@ impl Decodable for Inst {
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
match self {
Self::Mult { kind, mode, lhs, rhs } => Raw {
s: lhs.idx(),
t: rhs.idx(),
d: 0,
f: match (kind, mode) {
let [s, t, d, f] = match self {
Self::Mult { kind, mode, lhs, rhs } => [
lhs.idx(),
rhs.idx(),
0,
match (kind, mode) {
(MultKind::Mult, MultMode::Signed) => 0x8,
(MultKind::Mult, MultMode::Unsigned) => 0x9,
(MultKind::Div, MultMode::Signed) => 0xa,
(MultKind::Div, MultMode::Unsigned) => 0xb,
},
},
Self::MoveFrom { dst, src } => Raw {
s: 0,
t: 0,
d: dst.idx(),
f: match src {
],
Self::MoveFrom { dst, src } => [
0,
0,
dst.idx(),
match src {
MultReg::Hi => 0x0,
MultReg::Lo => 0x2,
},
},
Self::MoveTo { dst, src } => Raw {
s: src.idx(),
t: 0,
d: 0,
f: match dst {
],
Self::MoveTo { dst, src } => [
src.idx(),
0,
0,
match dst {
MultReg::Hi => 0x1,
MultReg::Lo => 0x3,
},
},
}
],
};
bitpack!("000000_sssss_ttttt_ddddd_?????_01ffff")
}
}

View File

@ -11,17 +11,6 @@ use crate::inst::{
InstFmt, Register,
};
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::From)]
pub enum Raw {
/// Immediate
Imm(imm::Raw),
/// Register
Reg(reg::Raw),
}
/// Alu register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::TryInto)]
@ -34,21 +23,19 @@ pub enum Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
fn decode(raw: Self::Raw) -> Option<Self> {
match raw {
Raw::Imm(raw) => Some(Self::Imm(imm::Inst::decode(raw)?)),
Raw::Reg(raw) => Some(Self::Reg(reg::Inst::decode(raw)?)),
}
None.or_else(|| imm::Inst::decode(raw).map(Self::Imm))
.or_else(|| reg::Inst::decode(raw).map(Self::Reg))
}
}
impl Encodable for Inst {
fn encode(&self) -> Self::Raw {
match self {
Self::Imm(inst) => Raw::Imm(inst.encode()),
Self::Reg(inst) => Raw::Reg(inst.encode()),
Self::Imm(inst) => inst.encode(),
Self::Reg(inst) => inst.encode(),
}
}
}

View File

@ -32,22 +32,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rt
pub t: u32,
/// Rd
pub d: u32,
/// Immediate
pub i: u32,
/// Function (lower 2 bits)
pub f: u32,
}
/// Shift immediate instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -65,10 +49,17 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
let [t, d, i, f] = #[bitmatch]
match raw {
"000000_?????_ttttt_ddddd_iiiii_0000ff" => [t, d, i, f],
_ => return None,
};
let kind = match f {
0x0 => Kind::LeftLogical,
0x2 => Kind::RightLogical,
0x3 => Kind::RightArithmetic,
@ -76,26 +67,27 @@ impl Decodable for Inst {
};
Some(Self {
dst: Register::new(raw.d)?,
lhs: Register::new(raw.t)?,
rhs: raw.i.truncated(),
dst: Register::new(d)?,
lhs: Register::new(t)?,
rhs: i.truncated(),
kind,
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let f = match self.kind {
let f: u32 = match self.kind {
Kind::LeftLogical => 0x0,
Kind::RightLogical => 0x2,
Kind::RightArithmetic => 0x3,
};
let t = self.lhs.idx();
let d = self.dst.idx();
let i = self.rhs.zero_extended();
let i = self.rhs.zero_extended::<u32>();
Raw { t, d, i, f }
bitpack!("000000_?????_ttttt_ddddd_iiiii_0000ff")
}
}

View File

@ -1,7 +1,10 @@
//! Shift register instructions
// Imports
use crate::inst::{InstFmt, Register, basic::{Decodable, Encodable, ModifiesReg}};
use crate::inst::{
basic::{Decodable, Encodable, ModifiesReg},
InstFmt, Register,
};
/// Shift register instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
@ -28,22 +31,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Rd
pub d: u32,
/// Func (lower 4 bits)
pub f: u32,
}
/// Shift register instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -61,10 +48,17 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
let [s, t, d, f] = #[bitmatch]
match raw {
"000000_sssss_ttttt_ddddd_?????_0001ff" => [s, t, d, f],
_ => return None,
};
let kind = match f {
0x0 => Kind::LeftLogical,
0x2 => Kind::RightLogical,
0x3 => Kind::RightArithmetic,
@ -72,16 +66,17 @@ impl Decodable for Inst {
};
Some(Self {
dst: Register::new(raw.d)?,
lhs: Register::new(raw.t)?,
rhs: Register::new(raw.s)?,
dst: Register::new(d)?,
lhs: Register::new(t)?,
rhs: Register::new(s)?,
kind,
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let f = match self.kind {
let f: u32 = match self.kind {
Kind::LeftLogical => 0x0,
Kind::RightLogical => 0x2,
Kind::RightArithmetic => 0x3,
@ -91,7 +86,7 @@ impl Encodable for Inst {
let t = self.lhs.idx();
let s = self.rhs.idx();
Raw { s, t, d, f }
bitpack!("000000_sssss_ttttt_ddddd_?????_0001ff")
}
}
@ -112,4 +107,4 @@ impl ModifiesReg for Inst {
fn modifies_reg(&self, reg: Register) -> bool {
self.dst == reg
}
}
}

View File

@ -42,22 +42,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Opcode (lower 3 bits)
pub p: u32,
/// Rs
pub s: u32,
/// Rt
pub t: u32,
/// Immediate
pub i: u32,
}
/// Store instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -75,10 +59,17 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.p {
let [p, s, t, i] = #[bitmatch]
match raw {
"101ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => [p, s, t, i],
_ => return None,
};
let kind = match p {
0x0 => Kind::Byte,
0x1 => Kind::HalfWord,
0x2 => Kind::WordLeft,
@ -88,16 +79,17 @@ impl Decodable for Inst {
};
Some(Self {
value: Register::new(raw.t)?,
addr: Register::new(raw.s)?,
offset: raw.i.truncated::<u16>().as_signed(),
value: Register::new(t)?,
addr: Register::new(s)?,
offset: i.truncated::<u16>().as_signed(),
kind,
})
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let p = match self.kind {
let p: u32 = match self.kind {
Kind::Byte => 0x0,
Kind::HalfWord => 0x1,
Kind::WordLeft => 0x2,
@ -108,7 +100,7 @@ impl Encodable for Inst {
let s = self.addr.idx();
let i = self.offset.as_unsigned().zero_extended::<u32>();
Raw { p, s, t, i }
bitpack!("101ppp_sssss_ttttt_iiiii_iiiii_iiiiii")
}
}

View File

@ -28,16 +28,6 @@ impl Kind {
}
}
/// Raw representation
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Raw {
/// Comment
pub c: u32,
/// Func (bottom bit)
pub f: u32,
}
/// Syscall instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct Inst {
@ -49,28 +39,36 @@ pub struct Inst {
}
impl Decodable for Inst {
type Raw = Raw;
type Raw = u32;
#[bitmatch::bitmatch]
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
let [c, f] = #[bitmatch]
match raw {
"000000_ccccc_ccccc_ccccc_ccccc_00110f" => [c, f],
_ => return None,
};
let kind = match f {
0 => Kind::Sys,
1 => Kind::Break,
_ => return None,
};
Some(Self { comment: raw.c, kind })
Some(Self { comment: c, kind })
}
}
impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> Self::Raw {
let c = self.comment;
let f = match self.kind {
let f: u32 = match self.kind {
Kind::Sys => 0,
Kind::Break => 1,
};
Raw { c, f }
bitpack!("000000_ccccc_ccccc_ccccc_ccccc_00110f")
}
}