mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 11:28:44 +00:00
Fixed basic::Inst not decoding everything correctly.
This commit is contained in:
parent
5ad6f6cb5e
commit
854d90858e
@ -23,6 +23,9 @@ pub enum Inst {
|
||||
/// Shift
|
||||
Shift(shift::Inst),
|
||||
|
||||
/// Multiplication
|
||||
Mult(mult::Inst),
|
||||
|
||||
/// Store
|
||||
Store(store::Inst),
|
||||
|
||||
@ -53,29 +56,18 @@ impl Decodable for Inst {
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
let inst = #[bitmatch]
|
||||
match raw {
|
||||
// Shift
|
||||
"000000_?????_ttttt_ddddd_iiiii_0000ff" => Self::Shift(shift::Inst::decode_from(shift::imm::Raw { t, d, i, f })?),
|
||||
"000000_sssss_ttttt_ddddd_?????_0001ff" => Self::Shift(shift::Inst::decode_from(shift::reg::Raw { s, t, d, f })?),
|
||||
|
||||
// Jump
|
||||
"00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => Self::Jmp(jmp::Inst::decode_from(jmp::imm::Raw { p, i })?),
|
||||
"000000_sssss_?????_ddddd_?????_00100f" => Self::Jmp(jmp::Inst::decode_from(jmp::reg::Raw { s, d, f })?),
|
||||
|
||||
"000000_ccccc_ccccc_ccccc_ccccc_00110f" => Self::Sys(sys::Inst::decode(sys::Raw { c, f })?),
|
||||
"000000_sssss_ttttt_ddddd_?????_01ffff" => Self::Mult(mult::Inst::decode(mult::Raw { s, t, d, f })?),
|
||||
"000000_sssss_ttttt_ddddd_?????_10ffff" => Self::Alu(alu::Inst::decode_from(alu::reg::Raw { s, t, d, f })?),
|
||||
"00001p_iiiii_iiiii_iiiii_iiiii_iiiiii" => Self::Jmp(jmp::Inst::decode_from(jmp::imm::Raw { p, i })?),
|
||||
"000ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Cond(cond::Inst::decode(cond::Raw { p, s, t, i })?),
|
||||
"001111_?????_ttttt_iiiii_iiiii_iiiiii" => Self::Lui(lui::Inst::decode(lui::Raw { t, i })?),
|
||||
|
||||
// Alu
|
||||
"000000_sssss_ttttt_ddddd_?????_10ffff" => Self::Alu(alu::Inst::decode_from(alu::reg::Raw { s, t, d, f })?),
|
||||
"001ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Alu(alu::Inst::decode_from(alu::imm::Raw { p, s, t, i })?),
|
||||
|
||||
// Syscall
|
||||
"000000_ccccc_ccccc_ccccc_ccccc_00110f" => Self::Sys(sys::Inst::decode(sys::Raw { c, f })?),
|
||||
|
||||
// Store / Load
|
||||
"100ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Store(store::Inst::decode(store::Raw { p, s, t, i })?),
|
||||
"101ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Load(load::Inst::decode(load::Raw { p, s, t, i })?),
|
||||
|
||||
// TODO: Remaining instructions, such as shift
|
||||
"100ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Load(load::Inst::decode(load::Raw { p, s, t, i })?),
|
||||
"101ppp_sssss_ttttt_iiiii_iiiii_iiiiii" => Self::Store(store::Inst::decode(store::Raw { p, s, t, i })?),
|
||||
|
||||
/*
|
||||
"0100nn_1iiii_iiiii_iiiii_iiiii_iiiiii" => CopN { n: n.truncate(), imm: i},
|
||||
@ -103,6 +95,10 @@ impl Encodable for Inst {
|
||||
shift::Raw::Imm(shift::imm::Raw { t, d, i, f }) => bitpack!("000000_?????_ttttt_ddddd_iiiii_0000ff"),
|
||||
shift::Raw::Reg(shift::reg::Raw { s, t, d, f }) => bitpack!("000000_sssss_ttttt_ddddd_?????_0001ff"),
|
||||
},
|
||||
Self::Mult(inst) => {
|
||||
let mult::Raw { s, t, d, f } = inst.encode();
|
||||
bitpack!("000000_sssss_ttttt_ddddd_?????_01ffff")
|
||||
},
|
||||
Self::Jmp(inst) => match inst.encode() {
|
||||
jmp::Raw::Imm(jmp::imm::Raw { p, i }) => bitpack!("00001p_iiiii_iiiii_iiiii_iiiii_iiiiii"),
|
||||
jmp::Raw::Reg(jmp::reg::Raw { s, d, f }) => bitpack!("000000_sssss_?????_ddddd_?????_00100f"),
|
||||
@ -141,6 +137,7 @@ impl InstFmt for Inst {
|
||||
Self::Store(inst) => inst.mnemonic(),
|
||||
Self::Load(inst) => inst.mnemonic(),
|
||||
Self::Cond(inst) => inst.mnemonic(),
|
||||
Self::Mult(inst) => inst.mnemonic(),
|
||||
Self::Jmp(inst) => inst.mnemonic(),
|
||||
Self::Alu(inst) => inst.mnemonic(),
|
||||
Self::Lui(inst) => inst.mnemonic(),
|
||||
@ -155,6 +152,7 @@ impl InstFmt for Inst {
|
||||
Self::Load(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Cond(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Jmp(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Mult(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Alu(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Lui(inst) => inst.fmt(pos, bytes, f),
|
||||
Self::Sys(inst) => inst.fmt(pos, bytes, f),
|
||||
|
||||
@ -136,7 +136,7 @@ impl InstFmt for Inst {
|
||||
}
|
||||
|
||||
fn fmt(&self, pos: crate::Pos, _bytes: &[u8], f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let address = pos + self.offset;
|
||||
let address = pos + 4 * self.offset;
|
||||
let mnemonic = self.kind.mnemonic();
|
||||
let arg = self.arg;
|
||||
|
||||
|
||||
@ -81,6 +81,6 @@ impl InstFmt for Inst {
|
||||
fn fmt(&self, _pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { kind, target } = self;
|
||||
|
||||
write!(f, "{} {target}", kind.mnemonic())
|
||||
write!(f, "{} {target:#x}", kind.mnemonic())
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,35 +6,30 @@ use crate::exe::inst::{
|
||||
InstFmt, Register,
|
||||
};
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// Load instruction kind
|
||||
///
|
||||
/// Each variant's value is equal to the lower 3 bits of the opcode
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
#[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum Kind {
|
||||
/// Byte, `i8`
|
||||
Byte = 0x0,
|
||||
Byte,
|
||||
|
||||
/// Half-word, `i16`
|
||||
HalfWord = 0x1,
|
||||
HalfWord,
|
||||
|
||||
/// Word left-bits, `u32`
|
||||
WordLeft = 0x2,
|
||||
WordLeft,
|
||||
|
||||
/// Word, `u32`
|
||||
Word = 0x3,
|
||||
Word,
|
||||
|
||||
/// Byte unsigned, `u8`
|
||||
ByteUnsigned = 0x4,
|
||||
ByteUnsigned,
|
||||
|
||||
/// Half-word unsigned, `u16`
|
||||
HalfWordUnsigned = 0x5,
|
||||
HalfWordUnsigned,
|
||||
|
||||
/// Word right-bits, `u32`
|
||||
WordRight = 0x6,
|
||||
WordRight,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
@ -89,23 +84,40 @@ impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
let op = Kind::try_from(raw.p.truncated::<u8>()).ok()?;
|
||||
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,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
src: Register::new(raw.t)?,
|
||||
dst: Register::new(raw.s)?,
|
||||
src: Register::new(raw.t)?,
|
||||
dst: Register::new(raw.s)?,
|
||||
offset: raw.i.truncated::<u16>().as_signed(),
|
||||
kind: op,
|
||||
kind,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
fn encode(&self) -> Raw {
|
||||
let p = match self.kind {
|
||||
Kind::Byte => 0x0,
|
||||
Kind::HalfWord => 0x1,
|
||||
Kind::WordLeft => 0x2,
|
||||
Kind::Word => 0x3,
|
||||
Kind::ByteUnsigned => 0x4,
|
||||
Kind::HalfWordUnsigned => 0x5,
|
||||
Kind::WordRight => 0x6,
|
||||
};
|
||||
let t = self.src.idx();
|
||||
let s = self.dst.idx();
|
||||
let i = self.offset.as_unsigned().zero_extended::<u32>();
|
||||
let p = u8::from(self.kind).zero_extended::<u32>();
|
||||
|
||||
Raw { p, s, t, i }
|
||||
}
|
||||
@ -119,7 +131,7 @@ impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, src, offset, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
let address = pos + *offset;
|
||||
let address = pos + 4 * offset;
|
||||
|
||||
write!(f, "{mnemonic} {dst}, {address}({src})")
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ pub struct Raw {
|
||||
/// Rd
|
||||
pub d: u32,
|
||||
|
||||
/// Func
|
||||
/// Func (bottom 4 bits)
|
||||
pub f: u32,
|
||||
}
|
||||
|
||||
@ -95,16 +95,19 @@ impl Decodable for Inst {
|
||||
#[rustfmt::skip]
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
Some(match raw.f {
|
||||
0x10 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Hi },
|
||||
0x12 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Lo },
|
||||
// 00x0
|
||||
0x0 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Hi },
|
||||
0x2 => Self::MoveFrom { dst: Register::new(raw.d)?, src: MultReg::Lo },
|
||||
|
||||
0x11 => Self::MoveTo { src: Register::new(raw.s)?, dst: MultReg::Hi },
|
||||
0x13 => Self::MoveTo { src: Register::new(raw.s)?, dst: 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 },
|
||||
|
||||
0x18 => Self::Mult { kind: MultKind::Mult, mode: MultMode:: Signed, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
|
||||
0x19 => Self::Mult { kind: MultKind::Mult, mode: MultMode::Unsigned, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
|
||||
0x1a => Self::Mult { kind: MultKind::Div , mode: MultMode:: Signed, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
|
||||
0x1b => Self::Mult { kind: MultKind::Div , mode: MultMode::Unsigned, lhs: Register::new(raw.s)?, rhs: Register::new(raw.t)? },
|
||||
// 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)? },
|
||||
|
||||
_ => return None,
|
||||
})
|
||||
@ -118,11 +121,12 @@ impl Encodable for Inst {
|
||||
s: lhs.idx(),
|
||||
t: rhs.idx(),
|
||||
d: 0,
|
||||
|
||||
f: match (kind, mode) {
|
||||
(MultKind::Mult, MultMode::Signed) => 0x18,
|
||||
(MultKind::Mult, MultMode::Unsigned) => 0x19,
|
||||
(MultKind::Div, MultMode::Signed) => 0x1a,
|
||||
(MultKind::Div, MultMode::Unsigned) => 0x1b,
|
||||
(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 {
|
||||
@ -130,8 +134,8 @@ impl Encodable for Inst {
|
||||
t: 0,
|
||||
d: dst.idx(),
|
||||
f: match src {
|
||||
MultReg::Hi => 0x10,
|
||||
MultReg::Lo => 0x12,
|
||||
MultReg::Hi => 0x0,
|
||||
MultReg::Lo => 0x2,
|
||||
},
|
||||
},
|
||||
Self::MoveTo { dst, src } => Raw {
|
||||
@ -139,8 +143,8 @@ impl Encodable for Inst {
|
||||
t: 0,
|
||||
d: 0,
|
||||
f: match dst {
|
||||
MultReg::Hi => 0x11,
|
||||
MultReg::Lo => 0x13,
|
||||
MultReg::Hi => 0x1,
|
||||
MultReg::Lo => 0x3,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -6,29 +6,24 @@ use crate::exe::inst::{
|
||||
InstFmt, Register,
|
||||
};
|
||||
use int_conv::{Signed, Truncated, ZeroExtended};
|
||||
use std::convert::TryFrom;
|
||||
|
||||
/// Store instruction kind
|
||||
///
|
||||
/// Each variant's value is equal to the lower 3 bits of the opcode
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
#[derive(num_enum::IntoPrimitive, num_enum::TryFromPrimitive)]
|
||||
#[repr(u8)]
|
||||
pub enum Kind {
|
||||
/// Byte, `u8`
|
||||
Byte = 0x0,
|
||||
/// Byte, `i8`
|
||||
Byte,
|
||||
|
||||
/// Half-word, `u16`
|
||||
HalfWord = 0x1,
|
||||
/// Half-word, `i16`
|
||||
HalfWord,
|
||||
|
||||
/// Word left-bits, `u32`
|
||||
WordLeft = 0x2,
|
||||
WordLeft,
|
||||
|
||||
/// Word, `u32`
|
||||
Word = 0x3,
|
||||
Word,
|
||||
|
||||
/// Word right-bits, `u32`
|
||||
WordRight = 0x6,
|
||||
WordRight,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
@ -81,7 +76,14 @@ impl Decodable for Inst {
|
||||
type Raw = Raw;
|
||||
|
||||
fn decode(raw: Self::Raw) -> Option<Self> {
|
||||
let kind = Kind::try_from(raw.p.truncated::<u8>()).ok()?;
|
||||
let kind = match raw.p {
|
||||
0x0 => Kind::Byte,
|
||||
0x1 => Kind::HalfWord,
|
||||
0x2 => Kind::WordLeft,
|
||||
0x3 => Kind::Word,
|
||||
0x6 => Kind::WordRight,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
src: Register::new(raw.t)?,
|
||||
@ -93,10 +95,16 @@ impl Decodable for Inst {
|
||||
}
|
||||
impl Encodable for Inst {
|
||||
fn encode(&self) -> Raw {
|
||||
let p = match self.kind {
|
||||
Kind::Byte => 0x0,
|
||||
Kind::HalfWord => 0x1,
|
||||
Kind::WordLeft => 0x2,
|
||||
Kind::Word => 0x3,
|
||||
Kind::WordRight => 0x6,
|
||||
};
|
||||
let t = self.src.idx();
|
||||
let s = self.dst.idx();
|
||||
let i = self.offset.as_unsigned().zero_extended::<u32>();
|
||||
let p = u8::from(self.kind).zero_extended::<u32>();
|
||||
|
||||
Raw { p, s, t, i }
|
||||
}
|
||||
@ -110,7 +118,7 @@ impl InstFmt for Inst {
|
||||
fn fmt(&self, pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let Self { dst, src, offset, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
let address = pos + *offset;
|
||||
let address = pos + 4 * offset;
|
||||
|
||||
write!(f, "{mnemonic} {dst}, {address}({src})")
|
||||
}
|
||||
|
||||
@ -83,6 +83,6 @@ impl InstFmt for Inst {
|
||||
let Self { comment, kind } = self;
|
||||
let mnemonic = kind.mnemonic();
|
||||
|
||||
write!(f, "{mnemonic}, {comment:#x}")
|
||||
write!(f, "{mnemonic} {comment:#x}")
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user