openvm_instructions/
lib.rs

1//! This crate is intended for use on host machine. This includes usage within procedural macros.
2
3#![allow(non_camel_case_types)]
4
5use openvm_instructions_derive::LocalOpcode;
6use openvm_stark_backend::p3_field::Field;
7use serde::{Deserialize, Serialize};
8use strum_macros::{EnumCount, EnumIter, FromRepr};
9
10pub mod exe;
11pub mod instruction;
12mod phantom;
13pub mod program;
14/// Module with traits and constants for RISC-V instruction definitions for custom OpenVM
15/// instructions.
16pub mod riscv;
17pub mod utils;
18
19pub use phantom::*;
20
21pub const NATIVE_AS: u32 = 4;
22
23pub trait LocalOpcode {
24    const CLASS_OFFSET: usize;
25    /// Convert from the discriminant of the enum to the typed enum variant.
26    /// Default implementation uses `from_repr`.
27    fn from_usize(value: usize) -> Self;
28    fn local_usize(&self) -> usize;
29
30    fn global_opcode_usize(&self) -> usize {
31        self.local_usize() + Self::CLASS_OFFSET
32    }
33    fn global_opcode(&self) -> VmOpcode {
34        VmOpcode::from_usize(self.global_opcode_usize())
35    }
36}
37
38#[repr(C)]
39#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, derive_new::new, Serialize, Deserialize)]
40pub struct VmOpcode(usize);
41
42impl VmOpcode {
43    /// Returns the corresponding `local_opcode_idx`
44    #[inline(always)]
45    pub const fn local_opcode_idx(&self, offset: usize) -> usize {
46        self.as_usize() - offset
47    }
48
49    /// Returns the opcode as a usize
50    #[inline(always)]
51    pub const fn as_usize(&self) -> usize {
52        self.0
53    }
54
55    /// Create a new [VmOpcode] from a usize
56    pub const fn from_usize(value: usize) -> Self {
57        Self(value)
58    }
59
60    /// Convert the VmOpcode into a field element
61    pub fn to_field<F: Field>(&self) -> F {
62        F::from_canonical_usize(self.as_usize())
63    }
64}
65
66impl std::fmt::Display for VmOpcode {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        write!(f, "{}", self.0)
69    }
70}
71
72// =================================================================================================
73// System opcodes
74// =================================================================================================
75
76#[derive(
77    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
78)]
79#[opcode_offset = 0]
80#[repr(usize)]
81pub enum SystemOpcode {
82    TERMINATE,
83    PHANTOM,
84}
85
86#[derive(
87    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
88)]
89#[opcode_offset = 0x020]
90#[repr(usize)]
91pub enum PublishOpcode {
92    PUBLISH,
93}
94
95// =================================================================================================
96// For internal dev use only
97// =================================================================================================
98
99#[derive(
100    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
101)]
102#[opcode_offset = 0xdeadaf]
103#[repr(usize)]
104pub enum UnimplementedOpcode {
105    REPLACE_ME,
106}