From aa3ec838193f71d0d77d9db603fc1217b0f32ac7 Mon Sep 17 00:00:00 2001 From: Ohad Nir <141617878+ohad-nir-starkware@users.noreply.github.com> Date: Tue, 11 Feb 2025 17:24:09 +0200 Subject: [PATCH] introduce opcode_extension to the structure of Instruction. (#1933) --- CHANGELOG.md | 2 + vm/src/types/instruction.rs | 6 ++ vm/src/vm/context/run_context.rs | 13 ++- vm/src/vm/decoding/decoder.rs | 141 ++++++++++++++++++------------- vm/src/vm/errors/vm_errors.rs | 4 +- vm/src/vm/vm_core.rs | 55 ++++++++++++ 6 files changed, 158 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be252bc857..95cfd2d722 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: add the field `opcode_extension` to the structure of `Instruction` [#1933](https://github.com/lambdaclass/cairo-vm/pull/1933) + * fix(BREAKING): Fix no trace padding flow in proof mode [#1909](https://github.com/lambdaclass/cairo-vm/pull/1909) * refactor: Limit ret opcode decodeing to Cairo0's standards. [#1925](https://github.com/lambdaclass/cairo-vm/pull/1925) diff --git a/vm/src/types/instruction.rs b/vm/src/types/instruction.rs index 133c691302..698f6e0500 100644 --- a/vm/src/types/instruction.rs +++ b/vm/src/types/instruction.rs @@ -27,6 +27,7 @@ pub struct Instruction { pub ap_update: ApUpdate, pub fp_update: FpUpdate, pub opcode: Opcode, + pub opcode_extension: OpcodeExtension, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] @@ -76,6 +77,11 @@ pub enum Opcode { Ret, } +#[derive(Clone, Debug, Copy, PartialEq, Eq)] +pub enum OpcodeExtension { + Stone, +} + impl Instruction { pub fn size(&self) -> usize { match self.op1_addr { diff --git a/vm/src/vm/context/run_context.rs b/vm/src/vm/context/run_context.rs index d5de5d41f5..e2fdb9e633 100644 --- a/vm/src/vm/context/run_context.rs +++ b/vm/src/vm/context/run_context.rs @@ -106,7 +106,7 @@ mod tests { use super::*; use crate::relocatable; use crate::stdlib::string::ToString; - use crate::types::instruction::{ApUpdate, FpUpdate, Opcode, PcUpdate, Res}; + use crate::types::instruction::{ApUpdate, FpUpdate, Opcode, OpcodeExtension, PcUpdate, Res}; use crate::utils::test_utils::mayberelocatable; use crate::vm::errors::memory_errors::MemoryError; use crate::Felt252; @@ -130,6 +130,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -158,6 +159,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -187,6 +189,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -215,6 +218,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -243,6 +247,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -271,6 +276,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -299,6 +305,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -327,6 +334,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -358,6 +366,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -388,6 +397,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { @@ -420,6 +430,7 @@ mod tests { ap_update: ApUpdate::Regular, fp_update: FpUpdate::Regular, opcode: Opcode::NOp, + opcode_extension: OpcodeExtension::Stone, }; let run_context = RunContext { diff --git a/vm/src/vm/decoding/decoder.rs b/vm/src/vm/decoding/decoder.rs index 8a018980f4..794fd95031 100644 --- a/vm/src/vm/decoding/decoder.rs +++ b/vm/src/vm/decoding/decoder.rs @@ -1,16 +1,18 @@ use crate::{ types::instruction::{ - ApUpdate, FpUpdate, Instruction, Op1Addr, Opcode, PcUpdate, Register, Res, + ApUpdate, FpUpdate, Instruction, Op1Addr, Opcode, OpcodeExtension, PcUpdate, Register, Res, }, vm::errors::vm_errors::VirtualMachineError, }; -// 0| opcode|ap_update|pc_update|res_logic|op1_src|op0_reg|dst_reg -// 15|14 13 12| 11 10| 9 8 7| 6 5|4 3 2| 1| 0 +// opcode_extension| opcode|ap_update|pc_update|res_logic|op1_src|op0_reg|dst_reg +// ... 15|14 13 12| 11 10| 9 8 7| 6 5|4 3 2| 1| 0 /// Decodes an instruction. The encoding is little endian, so flags go from bit 63 to 48. +/// The bits 64 and beyond are reserved for the opcode extension. +/// opcode_extension_num=0 means the instruction is a Stone instruction. +/// opcode_extension_num>1 is for new Stwo opcodes. pub fn decode_instruction(encoded_instr: u64) -> Result { - const HIGH_BIT: u64 = 1u64 << 63; const DST_REG_MASK: u64 = 0x0001; const DST_REG_OFF: u64 = 0; const OP0_REG_MASK: u64 = 0x0002; @@ -25,6 +27,7 @@ pub fn decode_instruction(encoded_instr: u64) -> Result Result> OFF0_OFF & OFFX_MASK); let off1 = decode_offset(encoded_instr >> OFF1_OFF & OFFX_MASK); @@ -53,6 +52,9 @@ pub fn decode_instruction(encoded_instr: u64) -> Result> AP_UPDATE_OFF; let opcode_num = (flags & OPCODE_MASK) >> OPCODE_OFF; + // Grab opcode_extension + let opcode_extension_num = encoded_instr >> OPCODE_EXTENSION_OFF; + // Match each flag to its corresponding enum value let dst_register = if dst_reg_num == 1 { Register::FP @@ -98,6 +100,15 @@ pub fn decode_instruction(encoded_instr: u64) -> Result return Err(VirtualMachineError::InvalidOpcode(opcode_num)), }; + let opcode_extension = match opcode_extension_num { + 0 => OpcodeExtension::Stone, + _ => { + return Err(VirtualMachineError::InvalidOpcodeExtension( + opcode_extension_num, + )) + } + }; + let ap_update = match (ap_update_num, opcode == Opcode::Call) { (0, true) => ApUpdate::Add2, (0, false) => ApUpdate::Regular, @@ -145,6 +156,7 @@ pub fn decode_instruction(encoded_instr: u64) -> Result