miden_processor/fast/
io_ops.rs

1use super::{DOUBLE_WORD_SIZE, ExecutionError, FastProcessor, Felt, WORD_SIZE_FELT};
2use crate::ErrorContext;
3
4impl FastProcessor {
5    /// Analogous to `Process::op_push`.
6    pub fn op_push(&mut self, element: Felt) {
7        self.increment_stack_size();
8        self.stack_write(0, element);
9    }
10
11    /// Analogous to `Process::op_advpop`.
12    #[inline(always)]
13    pub fn op_advpop(
14        &mut self,
15        op_idx: usize,
16        err_ctx: &impl ErrorContext,
17    ) -> Result<(), ExecutionError> {
18        let value = self
19            .advice
20            .pop_stack()
21            .map_err(|err| ExecutionError::advice_error(err, self.clk + op_idx, err_ctx))?;
22        self.increment_stack_size();
23        self.stack_write(0, value);
24        Ok(())
25    }
26
27    /// Analogous to `Process::op_advpopw`.
28    #[inline(always)]
29    pub fn op_advpopw(
30        &mut self,
31        op_idx: usize,
32        err_ctx: &impl ErrorContext,
33    ) -> Result<(), ExecutionError> {
34        let word = self
35            .advice
36            .pop_stack_word()
37            .map_err(|err| ExecutionError::advice_error(err, self.clk + op_idx, err_ctx))?;
38        self.stack_write_word(0, &word);
39
40        Ok(())
41    }
42
43    /// Analogous to `Process::op_mloadw`.
44    #[inline(always)]
45    pub fn op_mloadw(
46        &mut self,
47        op_idx: usize,
48        err_ctx: &impl ErrorContext,
49    ) -> Result<(), ExecutionError> {
50        let addr = self.stack_get(0);
51        self.decrement_stack_size();
52
53        let word = self
54            .memory
55            .read_word(self.ctx, addr, self.clk + op_idx, err_ctx)
56            .map_err(ExecutionError::MemoryError)?;
57        self.stack_write_word(0, &word);
58
59        Ok(())
60    }
61
62    /// Analogous to `Process::op_mstorew`.
63    #[inline(always)]
64    pub fn op_mstorew(
65        &mut self,
66        op_idx: usize,
67        err_ctx: &impl ErrorContext,
68    ) -> Result<(), ExecutionError> {
69        let addr = self.stack_get(0);
70        let word = self.stack_get_word(1);
71        self.decrement_stack_size();
72
73        self.memory
74            .write_word(self.ctx, addr, self.clk + op_idx, word, err_ctx)
75            .map_err(ExecutionError::MemoryError)?;
76        Ok(())
77    }
78
79    /// Analogous to `Process::op_mload`.
80    #[inline(always)]
81    pub fn op_mload(&mut self, err_ctx: &impl ErrorContext) -> Result<(), ExecutionError> {
82        let element = {
83            let addr = self.stack_get(0);
84            self.memory
85                .read_element(self.ctx, addr, err_ctx)
86                .map_err(ExecutionError::MemoryError)?
87        };
88
89        self.stack_write(0, element);
90
91        Ok(())
92    }
93
94    /// Analogous to `Process::op_mstore`.
95    #[inline(always)]
96    pub fn op_mstore(&mut self, err_ctx: &impl ErrorContext) -> Result<(), ExecutionError> {
97        let addr = self.stack_get(0);
98        let value = self.stack_get(1);
99        self.decrement_stack_size();
100
101        self.memory
102            .write_element(self.ctx, addr, value, err_ctx)
103            .map_err(ExecutionError::MemoryError)?;
104
105        Ok(())
106    }
107
108    /// Analogous to `Process::op_mstream`.
109    #[inline(always)]
110    pub fn op_mstream(
111        &mut self,
112        op_idx: usize,
113        err_ctx: &impl ErrorContext,
114    ) -> Result<(), ExecutionError> {
115        // The stack index where the memory address to load the words from is stored.
116        const MEM_ADDR_STACK_IDX: usize = 12;
117
118        // load two words from memory
119        let addr_first_word = self.stack_get(MEM_ADDR_STACK_IDX);
120        let addr_second_word = addr_first_word + WORD_SIZE_FELT;
121        let words = [
122            self.memory
123                .read_word(self.ctx, addr_first_word, self.clk + op_idx, err_ctx)
124                .map_err(ExecutionError::MemoryError)?,
125            self.memory
126                .read_word(self.ctx, addr_second_word, self.clk + op_idx, err_ctx)
127                .map_err(ExecutionError::MemoryError)?,
128        ];
129
130        // Replace the stack elements with the elements from memory (in stack order). The word at
131        // address `addr + 4` is at the top of the stack.
132        self.stack_write_word(0, &words[1]);
133        self.stack_write_word(4, &words[0]);
134
135        // increment the address by 8 (2 words)
136        self.stack_write(MEM_ADDR_STACK_IDX, addr_first_word + DOUBLE_WORD_SIZE);
137
138        Ok(())
139    }
140
141    /// Analogous to `Process::op_pipe`.
142    #[inline(always)]
143    pub fn op_pipe(
144        &mut self,
145        op_idx: usize,
146        err_ctx: &impl ErrorContext,
147    ) -> Result<(), ExecutionError> {
148        // The stack index where the memory address to load the words from is stored.
149        const MEM_ADDR_STACK_IDX: usize = 12;
150
151        let addr_first_word = self.stack_get(MEM_ADDR_STACK_IDX);
152        let addr_second_word = addr_first_word + WORD_SIZE_FELT;
153
154        // pop two words from the advice stack
155        let words = self
156            .advice
157            .pop_stack_dword()
158            .map_err(|err| ExecutionError::advice_error(err, self.clk + op_idx, err_ctx))?;
159
160        // write the words to memory
161        self.memory
162            .write_word(self.ctx, addr_first_word, self.clk + op_idx, words[0], err_ctx)
163            .map_err(ExecutionError::MemoryError)?;
164        self.memory
165            .write_word(self.ctx, addr_second_word, self.clk + op_idx, words[1], err_ctx)
166            .map_err(ExecutionError::MemoryError)?;
167
168        // replace the elements on the stack with the word elements (in stack order)
169        self.stack_write_word(0, &words[1]);
170        self.stack_write_word(4, &words[0]);
171
172        // increment the address by 8 (2 words)
173        self.stack_write(MEM_ADDR_STACK_IDX, addr_first_word + DOUBLE_WORD_SIZE);
174
175        Ok(())
176    }
177}