mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-07 18:31:14 +00:00
Added pseudo::Encodable.
This commit is contained in:
parent
9a580f4345
commit
48c21f5e88
@ -19,6 +19,7 @@ ascii = { version = "1.0.0", features = ["serde"] }
|
||||
int-conv = "0.1.4"
|
||||
bitmatch = "0.1.1"
|
||||
snailquote = "0.3.0"
|
||||
auto_enums = "0.7.12"
|
||||
|
||||
# Serde
|
||||
serde = { version = "1.0.120", features = ["derive"] }
|
||||
|
||||
@ -45,6 +45,21 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl IntoIterator<Item = basic::Inst>;
|
||||
|
||||
#[auto_enums::auto_enum(Iterator)]
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
match self {
|
||||
Inst::LoadImm(inst) => inst.encode(),
|
||||
Inst::Nop(inst) => inst.encode(),
|
||||
Inst::MoveReg(inst) => inst.encode(),
|
||||
Inst::Load(inst) => inst.encode(),
|
||||
Inst::Store(inst) => inst.encode(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
match self {
|
||||
@ -76,11 +91,12 @@ pub trait Decodable: InstSize + Sized {
|
||||
fn decode(insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self>;
|
||||
}
|
||||
|
||||
/*
|
||||
/// An encodable pseudo instruction
|
||||
pub trait Encodable: Decodable {
|
||||
/// Encodes this instruction
|
||||
pub trait Encodable {
|
||||
/// Iterator type
|
||||
type Iterator: IntoIterator<Item = basic::Inst>;
|
||||
|
||||
/// Encodes this instruction as basic instructions
|
||||
#[must_use]
|
||||
fn encode(&self) -> Self::Raw;
|
||||
fn encode(&self) -> Self::Iterator;
|
||||
}
|
||||
*/
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
//! Load instructions
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, InstSize, InstTarget, InstTargetFmt, Register},
|
||||
Pos,
|
||||
};
|
||||
use int_conv::{Join, SignExtended, Signed};
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
|
||||
/// Load pseudo instructions
|
||||
///
|
||||
@ -46,6 +46,31 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl Iterator<Item = basic::Inst>;
|
||||
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
let addr = self.target.0;
|
||||
let (lo, hi) = match addr.lo().as_signed() < 0 {
|
||||
true => (u16::MAX - addr.lo(), addr.hi().wrapping_add(1)),
|
||||
false => addr.lo_hi(),
|
||||
};
|
||||
|
||||
std::array::IntoIter::new([
|
||||
basic::Inst::Lui(basic::lui::Inst {
|
||||
dst: self.value,
|
||||
value: hi,
|
||||
}),
|
||||
basic::Inst::Load(basic::load::Inst {
|
||||
value: self.value,
|
||||
addr: self.value,
|
||||
offset: lo.as_signed(),
|
||||
kind: self.kind,
|
||||
}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
8
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
//! Load immediate
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, InstFmt, InstSize, InstTargetFmt, Register},
|
||||
Pos,
|
||||
};
|
||||
use dcb_util::SignedHex;
|
||||
use int_conv::{Join, SignExtended, Signed};
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
use std::convert::TryInto;
|
||||
|
||||
/// Immediate kind
|
||||
@ -105,6 +105,54 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl Iterator<Item = basic::Inst>;
|
||||
|
||||
#[auto_enums::auto_enum(Iterator)]
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
match self.kind {
|
||||
Kind::Address(Pos(addr)) => {
|
||||
let (lo, hi) = match addr.lo().as_signed() < 0 {
|
||||
true => (u16::MAX - addr.lo(), addr.hi().wrapping_add(1)),
|
||||
false => addr.lo_hi(),
|
||||
};
|
||||
|
||||
std::array::IntoIter::new([
|
||||
basic::Inst::Lui(basic::lui::Inst { dst: self.dst, value: hi }),
|
||||
basic::Inst::Alu(basic::alu::Inst::Imm(basic::alu::imm::Inst {
|
||||
dst: self.dst,
|
||||
lhs: self.dst,
|
||||
kind: basic::alu::imm::Kind::AddUnsigned(lo.as_signed()),
|
||||
})),
|
||||
])
|
||||
},
|
||||
Kind::Word(value) => {
|
||||
let (lo, hi) = value.lo_hi();
|
||||
|
||||
std::array::IntoIter::new([
|
||||
basic::Inst::Lui(basic::lui::Inst { dst: self.dst, value: hi }),
|
||||
basic::Inst::Alu(basic::alu::Inst::Imm(basic::alu::imm::Inst {
|
||||
dst: self.dst,
|
||||
lhs: self.dst,
|
||||
kind: basic::alu::imm::Kind::Or(lo),
|
||||
})),
|
||||
])
|
||||
},
|
||||
Kind::HalfWordUnsigned(value) => std::iter::once(basic::Inst::Alu(basic::alu::Inst::Imm(basic::alu::imm::Inst {
|
||||
dst: self.dst,
|
||||
lhs: Register::Zr,
|
||||
kind: basic::alu::imm::Kind::Or(value),
|
||||
}))),
|
||||
|
||||
Kind::HalfWordSigned(value) => std::iter::once(basic::Inst::Alu(basic::alu::Inst::Imm(basic::alu::imm::Inst {
|
||||
dst: self.dst,
|
||||
lhs: Register::Zr,
|
||||
kind: basic::alu::imm::Kind::AddUnsigned(value),
|
||||
}))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
match self.kind {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Move register instruction
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::inst::{basic, InstFmt, InstSize, Register};
|
||||
use std::convert::TryInto;
|
||||
|
||||
@ -35,6 +35,19 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl Iterator<Item = basic::Inst>;
|
||||
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
std::iter::once(basic::Inst::Alu(basic::alu::Inst::Reg(basic::alu::reg::Inst {
|
||||
dst: self.dst,
|
||||
lhs: self.src,
|
||||
rhs: Register::Zr,
|
||||
kind: basic::alu::reg::Kind::AddUnsigned,
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
4
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! Nop
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::inst::{basic, InstFmt, InstSize, Register};
|
||||
|
||||
/// No-op
|
||||
@ -10,25 +10,23 @@ use crate::inst::{basic, InstFmt, InstSize, Register};
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct Inst {
|
||||
/// Length of this nop, in instructions
|
||||
len: usize,
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
impl Inst {
|
||||
/// Instruction used by the nop
|
||||
pub const INST: basic::Inst = basic::Inst::Shift(basic::shift::Inst::Imm(basic::shift::imm::Inst {
|
||||
dst: Register::Zr,
|
||||
lhs: Register::Zr,
|
||||
rhs: 0,
|
||||
kind: basic::shift::imm::Kind::LeftLogical,
|
||||
}));
|
||||
}
|
||||
|
||||
impl Decodable for Inst {
|
||||
fn decode(insts: impl Iterator<Item = basic::Inst> + Clone) -> Option<Self> {
|
||||
// Get how many nops there are, in a row
|
||||
let len = insts
|
||||
.take_while(|inst| {
|
||||
matches!(
|
||||
inst,
|
||||
basic::Inst::Shift(basic::shift::Inst::Imm(basic::shift::imm::Inst {
|
||||
dst: Register::Zr,
|
||||
lhs: Register::Zr,
|
||||
rhs: 0,
|
||||
kind: basic::shift::imm::Kind::LeftLogical,
|
||||
}))
|
||||
)
|
||||
})
|
||||
.count();
|
||||
let len = insts.take_while(|inst| matches!(inst, &Self::INST)).count();
|
||||
|
||||
match len {
|
||||
0 => None,
|
||||
@ -37,6 +35,16 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl Iterator<Item = basic::Inst>;
|
||||
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
std::iter::repeat(Self::INST).take(self.len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
4 * self.len
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
//! Store instructions
|
||||
|
||||
// Imports
|
||||
use super::Decodable;
|
||||
use super::{Decodable, Encodable};
|
||||
use crate::{
|
||||
inst::{basic, InstSize, InstTarget, InstTargetFmt, Register},
|
||||
Pos,
|
||||
};
|
||||
use int_conv::{Join, SignExtended, Signed};
|
||||
use int_conv::{Join, SignExtended, Signed, Split};
|
||||
|
||||
/// Store pseudo instructions
|
||||
///
|
||||
@ -45,6 +45,31 @@ impl Decodable for Inst {
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Inst {
|
||||
type Iterator = impl Iterator<Item = basic::Inst>;
|
||||
|
||||
fn encode(&self) -> Self::Iterator {
|
||||
let addr = self.target.0;
|
||||
let (lo, hi) = match addr.lo().as_signed() < 0 {
|
||||
true => (u16::MAX - addr.lo(), addr.hi().wrapping_add(1)),
|
||||
false => addr.lo_hi(),
|
||||
};
|
||||
|
||||
std::array::IntoIter::new([
|
||||
basic::Inst::Lui(basic::lui::Inst {
|
||||
dst: Register::At,
|
||||
value: hi,
|
||||
}),
|
||||
basic::Inst::Store(basic::store::Inst {
|
||||
value: self.value,
|
||||
addr: Register::At,
|
||||
offset: lo.as_signed(),
|
||||
kind: self.kind,
|
||||
}),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl InstSize for Inst {
|
||||
fn size(&self) -> usize {
|
||||
8
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user