From 7203fac9e0b47684f4456f2b82fd66a0f90fda10 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Mon, 21 Oct 2024 21:33:53 +0200 Subject: [PATCH] zkaluvm: complete initial version --- src/core/microcode/base.rs | 8 ++++++ src/isa/gfa/bytecode.rs | 53 +++++++++++++++++++++++++++++++++++--- src/isa/gfa/exec.rs | 53 +++++++++++++++++++++++++++++++++++--- 3 files changed, 106 insertions(+), 8 deletions(-) diff --git a/src/core/microcode/base.rs b/src/core/microcode/base.rs index 124dbf9..b9fcf16 100644 --- a/src/core/microcode/base.rs +++ b/src/core/microcode/base.rs @@ -132,6 +132,14 @@ impl RegA { } } +impl From for RegA { + fn from(val: u8) -> Self { + let a = u3::with(val >> 5); + let idx = u5::with(val & 0x1F); + RegA::with(A::from(a), IdxA::from(idx)) + } +} + #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] #[display(inner)] pub struct IdxA(Idx32); diff --git a/src/isa/gfa/bytecode.rs b/src/isa/gfa/bytecode.rs index b3262ba..dcbc859 100644 --- a/src/isa/gfa/bytecode.rs +++ b/src/isa/gfa/bytecode.rs @@ -27,13 +27,30 @@ use std::ops::RangeInclusive; use amplify::num::u1; use super::FieldInstr; -use crate::core::SiteId; +use crate::core::{IdxAl, RegA, SiteId, A}; use crate::isa::{Bytecode, BytecodeRead, BytecodeWrite, CodeEofError}; +impl FieldInstr { + const START: u8 = 64; + const END: u8 = Self::START + Self::ADD_MUL; + const INC_MOD: u8 = 0; + const DEC_MOD: u8 = 1; + const NEG_MOD: u8 = 2; + const ADD_MUL: u8 = 3; +} + impl Bytecode for FieldInstr { - fn op_range() -> RangeInclusive { todo!() } + fn op_range() -> RangeInclusive { Self::START..=Self::END } - fn opcode_byte(&self) -> u8 { todo!() } + fn opcode_byte(&self) -> u8 { + Self::START + + match *self { + FieldInstr::IncMod { .. } => Self::INC_MOD, + FieldInstr::DecMod { .. } => Self::DEC_MOD, + FieldInstr::NegMod { .. } => Self::NEG_MOD, + FieldInstr::AddMod { .. } | FieldInstr::MulMod { .. } => Self::ADD_MUL, + } + } fn encode_operands(&self, writer: &mut W) -> Result<(), W::Error> where W: BytecodeWrite { @@ -72,6 +89,34 @@ impl Bytecode for FieldInstr { Self: Sized, R: BytecodeRead, { - todo!() + Ok(match opcode - Self::START { + Self::INC_MOD => { + let src_dst = RegA::from(reader.read_u8()?); + let val = reader.read_u8()?; + FieldInstr::IncMod { src_dst, val } + } + Self::DEC_MOD => { + let src_dst = RegA::from(reader.read_u8()?); + let val = reader.read_u8()?; + FieldInstr::IncMod { src_dst, val } + } + Self::NEG_MOD => { + let src_dst = RegA::from(reader.read_u8()?); + FieldInstr::NegMod { src_dst } + } + Self::ADD_MUL => { + let subop = reader.read_u1()?; + let reg = A::from(reader.read_u3()?); + let dst = IdxAl::from(reader.read_u4()?); + let src1 = IdxAl::from(reader.read_u4()?); + let src2 = IdxAl::from(reader.read_u4()?); + match subop { + u1::ZERO => FieldInstr::AddMod { reg, dst, src1, src2 }, + u1::ONE => FieldInstr::MulMod { reg, dst, src1, src2 }, + _ => unreachable!(), + } + } + _ => unreachable!(), + }) } } diff --git a/src/isa/gfa/exec.rs b/src/isa/gfa/exec.rs index 7268eee..b78b356 100644 --- a/src/isa/gfa/exec.rs +++ b/src/isa/gfa/exec.rs @@ -58,13 +58,58 @@ macro_rules! checked { impl Instruction for FieldInstr { type Context<'ctx> = (); - fn src_regs(&self) -> BTreeSet { todo!() } + fn src_regs(&self) -> BTreeSet { + match *self { + FieldInstr::IncMod { src_dst, val: _ } + | FieldInstr::DecMod { src_dst, val: _ } + | FieldInstr::NegMod { src_dst } => { + bset![src_dst.into()] + } + FieldInstr::AddMod { + reg, + dst, + src1: _, + src2: _, + } + | FieldInstr::MulMod { + reg, + dst, + src1: _, + src2: _, + } => bset![RegA::with(reg, dst.into()).into()], + } + } - fn dst_regs(&self) -> BTreeSet { todo!() } + fn dst_regs(&self) -> BTreeSet { + match *self { + FieldInstr::IncMod { src_dst, val: _ } + | FieldInstr::DecMod { src_dst, val: _ } + | FieldInstr::NegMod { src_dst } => { + bset![src_dst.into()] + } + FieldInstr::AddMod { + reg, + dst: _, + src1, + src2, + } + | FieldInstr::MulMod { + reg, + dst: _, + src1, + src2, + } => bset![RegA::with(reg, src1.into()).into(), RegA::with(reg, src2.into()).into()], + } + } - fn op_data_bytes(&self) -> u16 { todo!() } + fn op_data_bytes(&self) -> u16 { + match self { + FieldInstr::IncMod { .. } | FieldInstr::DecMod { .. } => 1, + FieldInstr::NegMod { .. } | FieldInstr::AddMod { .. } | FieldInstr::MulMod { .. } => 0, + } + } - fn ext_data_bytes(&self) -> u16 { todo!() } + fn ext_data_bytes(&self) -> u16 { 0 } fn complexity(&self) -> u64 { // Double the default complexity since each instruction performs two operations (and each arithmetic