diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index bf71a48..5fab65e 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1051,13 +1051,30 @@ impl Opcode { for i in entry.0..entry.1 { let pattern = OPCODE_PATTERNS[i as usize]; if (code & pattern.0) == pattern.1 { - // Safety: The enum is repr(u8) and marked non_exhaustive + // Safety: The enum is repr(u8) and the value is within the enum's range return unsafe { core::mem::transmute::(i) }; } } Self::Illegal } } +impl From for Opcode { + #[inline] + fn from(value: u8) -> Self { + if value > 221 { + Self::Illegal + } else { + // Safety: The enum is repr(u8) and the value is within the enum's range + unsafe { core::mem::transmute::(value) } + } + } +} +impl From for u8 { + #[inline] + fn from(value: Opcode) -> Self { + value as u8 + } +} impl Ins { /// simm: Signed Immediate #[inline(always)] diff --git a/genisa/src/disasm.rs b/genisa/src/disasm.rs index f131e8a..514defd 100644 --- a/genisa/src/disasm.rs +++ b/genisa/src/disasm.rs @@ -41,6 +41,8 @@ pub fn gen_disasm(isa: &Isa, max_args: usize) -> Result { entries.push(entry); } ensure!(sorted_ops.len() == isa.opcodes.len()); + ensure!(sorted_ops.len() <= 256); + let opcode_max = Literal::u8_unsuffixed((sorted_ops.len() - 1) as u8); // Generate the opcode entries table let mut opcode_entries = TokenStream::new(); @@ -337,13 +339,30 @@ pub fn gen_disasm(isa: &Isa, max_args: usize) -> Result { for i in entry.0..entry.1 { let pattern = OPCODE_PATTERNS[i as usize]; if (code & pattern.0) == pattern.1 { - #[comment = " Safety: The enum is repr(u8) and marked non_exhaustive"] + #[comment = " Safety: The enum is repr(u8) and the value is within the enum's range"] return unsafe { core::mem::transmute::(i) }; } } Self::Illegal } } + impl From for Opcode { + #[inline] + fn from(value: u8) -> Self { + if value > #opcode_max { + Self::Illegal + } else { + #[comment = " Safety: The enum is repr(u8) and the value is within the enum's range"] + unsafe { core::mem::transmute::(value) } + } + } + } + impl From for u8 { + #[inline] + fn from(value: Opcode) -> Self { + value as u8 + } + } impl Ins { #ins_fields