Skip to content

Commit

Permalink
isa: add Inst enum type over all supported instruction sets
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Nov 14, 2024
1 parent b00271f commit 1eb6a2e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/core/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

use core::fmt::{self, Debug, Formatter};

use aluvm::{CoreExt, Register};
use aluvm::{CoreExt, NoExt, Register};
use amplify::num::u4;

use crate::fe128;
Expand Down Expand Up @@ -87,6 +87,10 @@ impl Debug for GfaCore {
}
}

impl From<GfaCore> for NoExt {
fn from(_: GfaCore) -> Self { NoExt }
}

#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display)]
#[display(uppercase)]
#[repr(u8)]
Expand Down
41 changes: 39 additions & 2 deletions src/gfa/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@

use core::ops::RangeInclusive;

use aluvm::isa::{Bytecode, BytecodeRead, BytecodeWrite, CodeEofError};
use aluvm::isa::{Bytecode, BytecodeRead, BytecodeWrite, CodeEofError, CtrlInstr, ReservedInstr};
use aluvm::SiteId;

use super::{Bits, FieldInstr};
use super::{Bits, FieldInstr, Instr};
use crate::RegE;

impl FieldInstr {
Expand Down Expand Up @@ -103,3 +103,40 @@ impl<Id: SiteId> Bytecode<Id> for FieldInstr {
})
}
}

impl<Id: SiteId> Bytecode<Id> for Instr<Id> {
fn op_range() -> RangeInclusive<u8> { 0..=0xFF }

fn opcode_byte(&self) -> u8 {
match self {
Instr::Ctrl(instr) => instr.opcode_byte(),
Instr::Gfa(instr) => Bytecode::<Id>::opcode_byte(instr),
Instr::Reserved(instr) => Bytecode::<Id>::opcode_byte(instr),
}
}

fn encode_operands<W>(&self, writer: &mut W) -> Result<(), W::Error>
where W: BytecodeWrite<Id> {
match self {
Instr::Ctrl(instr) => instr.encode_operands(writer),
Instr::Gfa(instr) => instr.encode_operands(writer),
Instr::Reserved(instr) => instr.encode_operands(writer),
}
}

fn decode_operands<R>(reader: &mut R, opcode: u8) -> Result<Self, CodeEofError>
where
Self: Sized,
R: BytecodeRead<Id>,
{
match opcode {
op if CtrlInstr::<Id>::op_range().contains(&op) => {
CtrlInstr::<Id>::decode_operands(reader, op).map(Self::Ctrl)
}
op if <FieldInstr as Bytecode<Id>>::op_range().contains(&op) => {
FieldInstr::decode_operands(reader, op).map(Self::Gfa)
}
_ => ReservedInstr::decode_operands(reader, opcode).map(Self::Reserved),
}
}
}
65 changes: 63 additions & 2 deletions src/gfa/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use alloc::collections::BTreeSet;

use aluvm::isa::{ExecStep, Instruction};
use aluvm::regs::Status;
use aluvm::{Core, Site, SiteId};
use aluvm::{Core, CoreExt, Site, SiteId};

use super::{FieldInstr, ISA_GFA128};
use super::{FieldInstr, Instr, ISA_GFA128};
use crate::{GfaCore, RegE};

impl<Id: SiteId> Instruction<Id> for FieldInstr {
Expand Down Expand Up @@ -89,3 +89,64 @@ impl<Id: SiteId> Instruction<Id> for FieldInstr {
}
}
}

impl<Id: SiteId> Instruction<Id> for Instr<Id> {
const ISA_EXT: &'static [&'static str] = &[ISA_GFA128];
type Core = GfaCore;
type Context<'ctx> = ();

fn src_regs(&self) -> BTreeSet<<Self::Core as CoreExt>::Reg> {
match self {
Instr::Ctrl(_) => none!(),
Instr::Gfa(instr) => Instruction::<Id>::src_regs(instr),
Instr::Reserved(_) => none!(),
}
}

fn dst_regs(&self) -> BTreeSet<<Self::Core as CoreExt>::Reg> {
match self {
Instr::Ctrl(_) => none!(),
Instr::Gfa(instr) => Instruction::<Id>::dst_regs(instr),
Instr::Reserved(_) => none!(),
}
}

fn op_data_bytes(&self) -> u16 {
match self {
Instr::Ctrl(instr) => instr.op_data_bytes(),
Instr::Gfa(instr) => Instruction::<Id>::op_data_bytes(instr),
Instr::Reserved(_) => none!(),
}
}

fn ext_data_bytes(&self) -> u16 {
match self {
Instr::Ctrl(instr) => instr.ext_data_bytes(),
Instr::Gfa(instr) => Instruction::<Id>::ext_data_bytes(instr),
Instr::Reserved(_) => none!(),
}
}

fn exec(&self, site: Site<Id>, core: &mut Core<Id, Self::Core>, context: &Self::Context<'_>) -> ExecStep<Site<Id>> {
match self {
Instr::Ctrl(instr) => {
let mut subcore = Core::from(core.clone());
let step = instr.exec(site, &mut subcore, context);
*core = subcore.extend(core.cx.clone());
step
}
Instr::Gfa(instr) => {
let mut subcore = Core::from(core.clone());
let step = instr.exec(site, &mut subcore, context);
*core = subcore.extend(core.cx.clone());
step
}
Instr::Reserved(instr) => {
let mut subcore = Core::from(core.clone());
let step = instr.exec(site, &mut subcore, context);
*core = subcore.extend(core.cx.clone());
step
}
}
}
}
18 changes: 18 additions & 0 deletions src/gfa/instr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,28 @@
// or implied. See the License for the specific language governing permissions and limitations under
// the License.

use aluvm::isa::{CtrlInstr, ReservedInstr};
use aluvm::SiteId;
use amplify::num::u4;

use crate::RegE;

#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Display, From)]
#[display(inner)]
#[non_exhaustive]
pub enum Instr<Id: SiteId> {
/// Control flow instructions.
#[from]
Ctrl(CtrlInstr<Id>),

#[from]
Gfa(FieldInstr),

/// Reserved instruction for future use in core `ALU` ISAs.
#[from]
Reserved(ReservedInstr),
}

/// Arithmetic instructions for finite fields.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Display)]
#[non_exhaustive]
Expand Down
2 changes: 1 addition & 1 deletion src/gfa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ mod instr;
mod bytecode;
mod exec;

pub use instr::{Bits, FieldInstr};
pub use instr::{Bits, FieldInstr, Instr};

pub const ISA_GFA128: &str = "GFA128";

0 comments on commit 1eb6a2e

Please sign in to comment.