macro_rules! instruction {
($name:ident, $opcode:expr, $format:ty, {$($cty:ty: {$($cname:ident = $cvalue:expr);* $(;)?}),* $(,)?}) => {
impl $name {
$(
$(
pub const $cname: $cty = $cvalue;
)*
)*
}
crate::instruction::embive_macro::instruction!($name, $opcode, $format);
};
($name:ident, $opcode:expr, $format:ty) => {
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct $name (pub $format);
impl crate::instruction::embive::InstructionImpl for $name {
#[inline(always)]
fn opcode() -> u8 {
$opcode
}
#[inline(always)]
fn size() -> crate::format::Size {
<$format>::SIZE
}
#[inline(always)]
fn encode(&self) -> u32 {
self.0.to_embive()
}
#[inline(always)]
fn decode(inst: u32) -> Self {
Self(<$format>::from_embive(inst))
}
}
impl From<$format> for $name {
fn from(format: $format) -> Self {
Self(format)
}
}
};
}
macro_rules! instructions {
{$($opcode:expr => $name:ident: $format:ty = $consts:tt);* $(;)?} => {
$(
crate::instruction::embive_macro::instruction!($name, $opcode, $format, $consts);
)*
macro_rules! decode_instruction {
($inst:expr, $method:tt, $params:tt) => {
{
use crate::instruction::embive::InstructionImpl;
let inst = u32::from($inst);
match (inst & 0x1F) {
$(
$opcode => Some(crate::instruction::embive::$name::decode(inst).$method$params),
)*
_ => None,
}
}
};
}
pub(crate) use decode_instruction;
};
}
pub(super) use instruction;
pub(super) use instructions;