Skip to main content

powdr_syscalls/
lib.rs

1#![no_std]
2
3macro_rules! syscalls {
4    ($(($num:expr, $identifier:ident, $name:expr, $input_count:expr, $output_count:expr)),* $(,)?) => {
5        /// We use repr(u8) to make sure the enum discriminant will fit into the
6        /// 12 bits of the immediate field of the `addi` instruction,
7        #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
8        #[repr(u8)]
9        pub enum Syscall {
10            $($identifier = $num),*
11        }
12
13        impl Syscall {
14            pub const fn name(&self) -> &'static str {
15                match self {
16                    $(Syscall::$identifier => $name),*
17                }
18            }
19
20            pub const fn arity(&self) -> (u32, u32) {
21                match self {
22                    $(Syscall::$identifier => ($input_count, $output_count)),*
23                }
24            }
25        }
26
27        impl core::fmt::Display for Syscall {
28            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
29                write!(f, "{}", match self {
30                    $(Syscall::$identifier => $name),*
31                })
32            }
33        }
34
35        impl core::str::FromStr for Syscall {
36            type Err = ();
37            fn from_str(input: &str) -> Result<Self, Self::Err> {
38                match input {
39                    $($name => Ok(Syscall::$identifier)),*,
40                    _ => Err(()),
41                }
42            }
43        }
44
45        impl From<Syscall> for u8 {
46            fn from(syscall: Syscall) -> Self {
47                syscall as Self
48            }
49        }
50
51        impl core::convert::TryFrom<u8> for Syscall {
52            type Error = ();
53            fn try_from(value: u8) -> Result<Self, Self::Error> {
54                match value {
55                    $($num => Ok(Syscall::$identifier)),*,
56                    _ => Err(()),
57                }
58            }
59        }
60    }
61}
62
63// Generate `Syscall` enum with supported syscalls and their numbers.
64syscalls!(
65    (1, Input, "input", 2, 1),
66    (2, Output, "output", 2, 0),
67    (3, PoseidonGL, "poseidon_gl", 1, 0),
68    (4, Affine256, "affine_256", 4, 0),
69    (5, EcAdd, "ec_add", 3, 0),
70    (6, EcDouble, "ec_double", 2, 0),
71    (7, KeccakF, "keccakf", 2, 0),
72    (8, Mod256, "mod_256", 3, 0),
73    (9, Halt, "halt", 0, 0),
74    (10, Poseidon2GL, "poseidon2_gl", 2, 0),
75    (11, NativeHash, "native_hash", 1, 0),
76    (12, CommitPublic, "commit_public", 2, 0),
77    (13, InvertGL, "invert_gl", 2, 2),
78    (14, SplitGLVec, "split_gl_vec", 2, 0),
79    (15, MergeGL, "merge_gl", 3, 0),
80);