use miden_air::Felt;
use crate::{
ErrorContext, ExecutionError,
fast::Tracer,
processor::{
AdviceProviderInterface, MemoryInterface, Processor, StackInterface, SystemInterface,
},
};
#[inline(always)]
pub(super) fn op_advpop<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let value = processor
.advice_provider()
.pop_stack()
.map_err(|err| ExecutionError::advice_error(err, processor.system().clk(), err_ctx))?;
tracer.record_advice_pop_stack(value);
processor.stack().increment_size(tracer)?;
processor.stack().set(0, value);
Ok(())
}
#[inline(always)]
pub(super) fn op_advpopw<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let word = processor
.advice_provider()
.pop_stack_word()
.map_err(|err| ExecutionError::advice_error(err, processor.system().clk(), err_ctx))?;
tracer.record_advice_pop_stack_word(word);
processor.stack().set_word(0, &word);
Ok(())
}
#[inline(always)]
pub(super) fn op_mloadw<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let addr = processor.stack().get(0);
let ctx = processor.system().ctx();
let clk = processor.system().clk();
processor.stack().decrement_size(tracer);
let word = processor
.memory()
.read_word(ctx, addr, clk, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_read_word(word, addr, processor.system().ctx(), processor.system().clk());
processor.stack().set_word(0, &word);
Ok(())
}
#[inline(always)]
pub(super) fn op_mstorew<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let addr = processor.stack().get(0);
let word = processor.stack().get_word(1);
let ctx = processor.system().ctx();
let clk = processor.system().clk();
processor.stack().decrement_size(tracer);
processor
.memory()
.write_word(ctx, addr, clk, word, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_write_word(word, addr, processor.system().ctx(), processor.system().clk());
Ok(())
}
#[inline(always)]
pub(super) fn op_mload<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let ctx = processor.system().ctx();
let addr = processor.stack().get(0);
let element = processor
.memory()
.read_element(ctx, addr, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_read_element(
element,
addr,
processor.system().ctx(),
processor.system().clk(),
);
processor.stack().set(0, element);
Ok(())
}
#[inline(always)]
pub(super) fn op_mstore<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
let addr = processor.stack().get(0);
let value = processor.stack().get(1);
let ctx = processor.system().ctx();
processor.stack().decrement_size(tracer);
processor
.memory()
.write_element(ctx, addr, value, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_write_element(
value,
addr,
processor.system().ctx(),
processor.system().clk(),
);
Ok(())
}
#[inline(always)]
pub(super) fn op_mstream<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
const WORD_SIZE_FELT: Felt = Felt::new(4);
const DOUBLE_WORD_SIZE: Felt = Felt::new(8);
const MEM_ADDR_STACK_IDX: usize = 12;
let ctx = processor.system().ctx();
let clk = processor.system().clk();
let addr_first_word = processor.stack().get(MEM_ADDR_STACK_IDX);
let words = {
let addr_second_word = addr_first_word + WORD_SIZE_FELT;
let first_word = processor
.memory()
.read_word(ctx, addr_first_word, clk, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_read_word(
first_word,
addr_first_word,
processor.system().ctx(),
processor.system().clk(),
);
let second_word = processor
.memory()
.read_word(ctx, addr_second_word, clk, err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_read_word(
second_word,
addr_second_word,
processor.system().ctx(),
processor.system().clk(),
);
[first_word, second_word]
};
processor.stack().set_word(0, &words[1]);
processor.stack().set_word(4, &words[0]);
processor.stack().set(MEM_ADDR_STACK_IDX, addr_first_word + DOUBLE_WORD_SIZE);
Ok(())
}
#[inline(always)]
pub(super) fn op_pipe<P: Processor>(
processor: &mut P,
err_ctx: &impl ErrorContext,
tracer: &mut impl Tracer,
) -> Result<(), ExecutionError> {
const WORD_SIZE_FELT: Felt = Felt::new(4);
const DOUBLE_WORD_SIZE: Felt = Felt::new(8);
const MEM_ADDR_STACK_IDX: usize = 12;
let clk = processor.system().clk();
let ctx = processor.system().ctx();
let addr_first_word = processor.stack().get(MEM_ADDR_STACK_IDX);
let addr_second_word = addr_first_word + WORD_SIZE_FELT;
let words = processor
.advice_provider()
.pop_stack_dword()
.map_err(|err| ExecutionError::advice_error(err, clk, err_ctx))?;
tracer.record_advice_pop_stack_dword(words);
processor
.memory()
.write_word(ctx, addr_first_word, clk, words[0], err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_write_word(
words[0],
addr_first_word,
processor.system().ctx(),
processor.system().clk(),
);
processor
.memory()
.write_word(ctx, addr_second_word, clk, words[1], err_ctx)
.map_err(ExecutionError::MemoryError)?;
tracer.record_memory_write_word(
words[1],
addr_second_word,
processor.system().ctx(),
processor.system().clk(),
);
processor.stack().set_word(0, &words[1]);
processor.stack().set_word(4, &words[0]);
processor.stack().set(MEM_ADDR_STACK_IDX, addr_first_word + DOUBLE_WORD_SIZE);
Ok(())
}