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 instructions.
15pub mod riscv;
16pub mod utils;
17
18pub use phantom::*;
19
20pub trait LocalOpcode {
21    const CLASS_OFFSET: usize;
22    /// Convert from the discriminant of the enum to the typed enum variant.
23    /// Default implementation uses `from_repr`.
24    fn from_usize(value: usize) -> Self;
25    fn local_usize(&self) -> usize;
26
27    fn global_opcode(&self) -> VmOpcode {
28        VmOpcode::from_usize(self.local_usize() + Self::CLASS_OFFSET)
29    }
30}
31
32#[repr(C)]
33#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, derive_new::new, Serialize, Deserialize)]
34pub struct VmOpcode(usize);
35
36impl VmOpcode {
37    /// Returns the corresponding `local_opcode_idx`
38    pub fn local_opcode_idx(&self, offset: usize) -> usize {
39        self.as_usize() - offset
40    }
41
42    /// Returns the opcode as a usize
43    pub fn as_usize(&self) -> usize {
44        self.0
45    }
46
47    /// Create a new [VmOpcode] from a usize
48    pub fn from_usize(value: usize) -> Self {
49        Self(value)
50    }
51
52    /// Convert the VmOpcode into a field element
53    pub fn to_field<F: Field>(&self) -> F {
54        F::from_canonical_usize(self.as_usize())
55    }
56}
57
58impl std::fmt::Display for VmOpcode {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        write!(f, "{}", self.0)
61    }
62}
63
64// =================================================================================================
65// System opcodes
66// =================================================================================================
67
68#[derive(
69    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
70)]
71#[opcode_offset = 0]
72#[repr(usize)]
73pub enum SystemOpcode {
74    TERMINATE,
75    PHANTOM,
76}
77
78#[derive(
79    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
80)]
81#[opcode_offset = 0x020]
82#[repr(usize)]
83pub enum PublishOpcode {
84    PUBLISH,
85}
86
87// =================================================================================================
88// For internal dev use only
89// =================================================================================================
90
91#[derive(
92    Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, EnumCount, EnumIter, FromRepr, LocalOpcode,
93)]
94#[opcode_offset = 0xdeadaf]
95#[repr(usize)]
96pub enum UnimplementedOpcode {
97    REPLACE_ME,
98}