use core::fmt;
use super::flags::FlagEffects;
use super::inst::Op;
use super::reg::{Reg, Size};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum OperandKind {
Reg(Size),
RegMem(Size),
Mem(Size),
Fixed(Reg),
One,
Imm {
bits: u8,
signed: bool,
},
Rel {
bits: u8,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Slot {
Implied,
Reg,
Rm,
Opcode,
Imm,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum ModRmSpec {
Absent,
Reg,
Ext(u8),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum OpcodeField {
Fixed,
Reg,
Cond,
}
pub(crate) const ATTR_D64: u8 = 1;
pub(crate) const ATTR_NOT_R0: u8 = 2;
#[derive(Clone, Copy)]
pub struct Form {
pub(crate) kinds: [OperandKind; 3],
pub(crate) slots: [Slot; 3],
pub(crate) flags: FlagEffects,
pub(crate) id: u16,
pub(crate) op: Op,
pub(crate) count: u8,
pub(crate) map: u8,
pub(crate) opcode: u8,
pub(crate) field: OpcodeField,
pub(crate) modrm: ModRmSpec,
pub(crate) imm_bytes: u8,
pub(crate) p66: bool,
pub(crate) rex_w: bool,
pub(crate) attrs: u8,
pub(crate) reads_cond: bool,
pub(crate) rm_mem_only: bool,
pub(crate) encoding: &'static str,
pub(crate) syntax: &'static str,
}
impl Form {
#[inline]
#[must_use]
pub const fn encoding(&self) -> &'static str {
self.encoding
}
#[inline]
#[must_use]
pub const fn syntax(&self) -> &'static str {
self.syntax
}
#[inline]
#[must_use]
pub fn operands(&self) -> &[OperandKind] {
&self.kinds[..usize::from(self.count).min(3)]
}
#[inline]
#[must_use]
pub const fn flags(&self) -> FlagEffects {
self.flags
}
#[inline]
#[must_use]
pub const fn reads_condition(&self) -> bool {
self.reads_cond
}
#[inline]
#[must_use]
pub const fn index(&self) -> usize {
self.id as usize
}
}
impl PartialEq for Form {
fn eq(&self, other: &Form) -> bool {
self.id == other.id
}
}
impl Eq for Form {}
impl fmt::Display for Form {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{} | {}", self.encoding, self.syntax)
}
}
impl fmt::Debug for Form {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Form({self})")
}
}