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