use crate::decoder::sync;
use crate::instruction::{self, info, Instruction};
use crate::types::{trap, Privilege};
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct Item<I: info::Info = Option<instruction::Kind>> {
pc: u64,
kind: Kind<I>,
}
impl<I: info::Info> Item<I> {
pub fn new(pc: u64, kind: Kind<I>) -> Self {
Self { pc, kind }
}
pub fn pc(&self) -> u64 {
self.pc
}
pub fn kind(&self) -> &Kind<I> {
&self.kind
}
pub fn instruction(&self) -> Option<&Instruction<I>> {
match &self.kind {
Kind::Regular(insn) => Some(insn),
_ => None,
}
}
pub fn trap(&self) -> Option<&trap::Info> {
match &self.kind {
Kind::Trap(info) => Some(info),
_ => None,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Kind<I: info::Info = Option<instruction::Kind>> {
Regular(Instruction<I>),
Trap(trap::Info),
Context(Context),
}
impl<I: info::Info> From<Instruction<I>> for Kind<I> {
fn from(insn: Instruction<I>) -> Self {
Self::Regular(insn)
}
}
impl From<instruction::Kind> for Kind<Option<instruction::Kind>> {
fn from(insn: instruction::Kind) -> Self {
Self::Regular(insn.into())
}
}
impl<I: info::Info> From<trap::Info> for Kind<I> {
fn from(info: trap::Info) -> Self {
Self::Trap(info)
}
}
impl<I: info::Info> From<Context> for Kind<I> {
fn from(context: Context) -> Self {
Self::Context(context)
}
}
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Hash)]
pub struct Context {
pub privilege: Privilege,
pub context: u64,
}
impl From<&sync::Context> for Context {
fn from(ctx: &sync::Context) -> Self {
Self {
privilege: ctx.privilege,
context: ctx.context.unwrap_or_default(),
}
}
}
impl From<sync::Context> for Context {
fn from(ctx: sync::Context) -> Self {
(&ctx).into()
}
}