Added basic::shift instruction.

This commit is contained in:
2021-01-08 16:15:28 +00:00
parent 058da819ee
commit 5ad6f6cb5e
4 changed files with 308 additions and 0 deletions

View File

@@ -10,6 +10,7 @@ pub mod jmp;
pub mod load;
pub mod lui;
pub mod mult;
pub mod shift;
pub mod store;
pub mod sys;
@@ -19,6 +20,9 @@ use crate::exe::inst::InstFmt;
/// All basic instructions
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Inst {
/// Shift
Shift(shift::Inst),
/// Store
Store(store::Inst),
@@ -49,6 +53,10 @@ 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 })?),
@@ -91,6 +99,10 @@ impl Encodable for Inst {
#[bitmatch::bitmatch]
fn encode(&self) -> u32 {
match self {
Self::Shift(inst) => match inst.encode() {
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::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"),
@@ -133,6 +145,7 @@ impl InstFmt for Inst {
Self::Alu(inst) => inst.mnemonic(),
Self::Lui(inst) => inst.mnemonic(),
Self::Sys(inst) => inst.mnemonic(),
Self::Shift(inst) => inst.mnemonic(),
}
}
@@ -145,6 +158,7 @@ impl InstFmt for Inst {
Self::Alu(inst) => inst.fmt(pos, bytes, f),
Self::Lui(inst) => inst.fmt(pos, bytes, f),
Self::Sys(inst) => inst.fmt(pos, bytes, f),
Self::Shift(inst) => inst.fmt(pos, bytes, f),
}
}
}

View File

@@ -0,0 +1,69 @@
//! Shift instruction
// Modules
pub mod imm;
pub mod reg;
// Imports
use crate::exe::inst::{
basic::{Decodable, Encodable},
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)]
pub enum Inst {
/// Immediate
Imm(imm::Inst),
/// Register
Reg(reg::Inst),
}
impl Decodable for Inst {
type Raw = Raw;
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)?)),
}
}
}
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()),
}
}
}
impl InstFmt for Inst {
fn mnemonic(&self) -> &'static str {
match self {
Self::Imm(inst) => inst.mnemonic(),
Self::Reg(inst) => inst.mnemonic(),
}
}
fn fmt(&self, pos: crate::Pos, bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Imm(inst) => inst.fmt(pos, bytes, f),
Self::Reg(inst) => inst.fmt(pos, bytes, f),
}
}
}

View File

@@ -0,0 +1,113 @@
//! Shift immediate instructions
// Imports
use crate::exe::inst::{
basic::{Decodable, Encodable},
InstFmt, Register,
};
use int_conv::{Truncated, ZeroExtended};
/// Shift immediate instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Kind {
/// Left logical
LeftLogical,
/// Right logical
RightLogical,
/// Right arithmetic
RightArithmetic,
}
impl Kind {
/// Returns this kind's mnemonic
#[must_use]
pub const fn mnemonic(self) -> &'static str {
match self {
Self::LeftLogical => "sll",
Self::RightLogical => "srl",
Self::RightArithmetic => "sra",
}
}
}
/// 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 {
/// Destination register
pub dst: Register,
/// Lhs argument
pub lhs: Register,
/// Rhs argument
pub rhs: u8,
/// Kind
pub kind: Kind,
}
impl Decodable for Inst {
type Raw = Raw;
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
0x0 => Kind::LeftLogical,
0x2 => Kind::RightLogical,
0x3 => Kind::RightArithmetic,
_ => return None,
};
Some(Self {
dst: Register::new(raw.d)?,
lhs: Register::new(raw.t)?,
rhs: raw.i.truncated(),
kind,
})
}
}
impl Encodable for Inst {
fn encode(&self) -> Self::Raw {
let f = 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();
Raw { t, d, i, f }
}
}
impl InstFmt for Inst {
fn mnemonic(&self) -> &'static str {
self.kind.mnemonic()
}
fn fmt(&self, _pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
let Self { dst, lhs, rhs, kind } = self;
let mnemonic = kind.mnemonic();
write!(f, "{mnemonic} {dst}, {lhs}, {rhs}")
}
}

View File

@@ -0,0 +1,112 @@
//! Shift register instructions
// Imports
use crate::exe::inst::{
basic::{Decodable, Encodable},
InstFmt, Register,
};
/// Shift register instruction kind
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum Kind {
/// Left logical
LeftLogical,
/// Right logical
RightLogical,
/// Right arithmetic
RightArithmetic,
}
impl Kind {
/// Returns this kind's mnemonic
#[must_use]
pub const fn mnemonic(self) -> &'static str {
match self {
Self::LeftLogical => "sllv",
Self::RightLogical => "srlv",
Self::RightArithmetic => "srav",
}
}
}
/// 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 {
/// Destination register
pub dst: Register,
/// Lhs argument
pub lhs: Register,
/// Rhs argument
pub rhs: Register,
/// Kind
pub kind: Kind,
}
impl Decodable for Inst {
type Raw = Raw;
fn decode(raw: Self::Raw) -> Option<Self> {
let kind = match raw.f {
0x0 => Kind::LeftLogical,
0x2 => Kind::RightLogical,
0x3 => Kind::RightArithmetic,
_ => return None,
};
Some(Self {
dst: Register::new(raw.d)?,
lhs: Register::new(raw.t)?,
rhs: Register::new(raw.s)?,
kind,
})
}
}
impl Encodable for Inst {
fn encode(&self) -> Raw {
let f = match self.kind {
Kind::LeftLogical => 0x0,
Kind::RightLogical => 0x2,
Kind::RightArithmetic => 0x3,
};
let d = self.dst.idx();
let t = self.lhs.idx();
let s = self.rhs.idx();
Raw { s, t, d, f }
}
}
impl InstFmt for Inst {
fn mnemonic(&self) -> &'static str {
self.kind.mnemonic()
}
fn fmt(&self, _pos: crate::Pos, _bytes: &[u8], f: &mut std::fmt::Formatter) -> std::fmt::Result {
let Self { dst, lhs, rhs, kind } = self;
let mnemonic = kind.mnemonic();
write!(f, "{mnemonic} {dst}, {lhs}, {rhs}")
}
}