2023-06-20 19:07:48 -05:00
|
|
|
#![no_std]
|
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
pub type OpR = u8;
|
2023-07-25 16:43:06 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
pub type OpA = u64;
|
|
|
|
pub type OpO = u32;
|
|
|
|
pub type OpP = u16;
|
|
|
|
|
|
|
|
pub type OpB = u8;
|
|
|
|
pub type OpH = u16;
|
|
|
|
pub type OpW = u32;
|
|
|
|
pub type OpD = u64;
|
2023-06-20 19:07:48 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
/// # Safety
|
|
|
|
/// Has to be valid to be decoded from bytecode.
|
|
|
|
pub unsafe trait BytecodeItem {}
|
|
|
|
macro_rules! define_items {
|
|
|
|
($($name:ident ($($item:ident),* $(,)?)),* $(,)?) => {
|
|
|
|
$(
|
|
|
|
#[repr(packed)]
|
|
|
|
pub struct $name($(pub $item),*);
|
|
|
|
unsafe impl BytecodeItem for $name {}
|
|
|
|
)*
|
2023-07-25 16:43:06 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
define_items! {
|
|
|
|
OpsRR (OpR, OpR ),
|
|
|
|
OpsRRR (OpR, OpR, OpR ),
|
|
|
|
OpsRRRR (OpR, OpR, OpR, OpR),
|
|
|
|
OpsRRB (OpR, OpR, OpB ),
|
|
|
|
OpsRRH (OpR, OpR, OpH ),
|
|
|
|
OpsRRW (OpR, OpR, OpW ),
|
|
|
|
OpsRD (OpR, OpD ),
|
|
|
|
OpsRRD (OpR, OpR, OpD ),
|
|
|
|
OpsRRAH (OpR, OpR, OpA, OpH),
|
|
|
|
OpsRROH (OpR, OpR, OpO, OpH),
|
|
|
|
OpsRRO (OpR, OpR, OpO ),
|
|
|
|
OpsRRP (OpR, OpR, OpP ),
|
|
|
|
}
|
2023-08-08 18:24:13 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
unsafe impl BytecodeItem for OpA {}
|
|
|
|
unsafe impl BytecodeItem for OpB {}
|
|
|
|
unsafe impl BytecodeItem for OpO {}
|
|
|
|
unsafe impl BytecodeItem for () {}
|
2023-08-08 18:24:13 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
::with_builtin_macros::with_builtin! {
|
|
|
|
let $spec = include_from_root!("instructions.in") in {
|
|
|
|
/// Invoke macro with bytecode definition
|
|
|
|
///
|
|
|
|
/// # Format
|
|
|
|
/// ```text
|
|
|
|
/// Opcode, Mnemonic, Type, Docstring;
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// # Type
|
|
|
|
/// ```text
|
|
|
|
/// Types consist of letters meaning a single field
|
|
|
|
/// | Type | Size (B) | Meaning |
|
|
|
|
/// |:-----|:---------|:------------------------|
|
|
|
|
/// | N | 0 | Empty |
|
|
|
|
/// | R | 1 | Register |
|
|
|
|
/// | A | 8 | Absolute address |
|
|
|
|
/// | O | 4 | Relative address offset |
|
|
|
|
/// | P | 2 | Relative address offset |
|
|
|
|
/// | B | 1 | Immediate |
|
|
|
|
/// | H | 2 | Immediate |
|
|
|
|
/// | W | 4 | Immediate |
|
|
|
|
/// | D | 8 | Immediate |
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
macro_rules! invoke_with_def {
|
|
|
|
($macro:path) => {
|
|
|
|
$macro! { $spec }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-20 19:07:48 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
macro_rules! gen_opcodes {
|
|
|
|
($($opcode:expr, $mnemonic:ident, $_ty:ident, $doc:literal;)*) => {
|
|
|
|
pub mod opcode {
|
|
|
|
$(
|
|
|
|
#[doc = $doc]
|
|
|
|
pub const $mnemonic: u8 = $opcode;
|
|
|
|
)*
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2023-06-20 19:07:48 -05:00
|
|
|
|
2023-09-26 16:36:27 -05:00
|
|
|
invoke_with_def!(gen_opcodes);
|