Skip to content

Commit

Permalink
isa: complete ALU basic ISA execution
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Oct 21, 2024
1 parent e313223 commit b170f5f
Show file tree
Hide file tree
Showing 10 changed files with 307 additions and 78 deletions.
40 changes: 18 additions & 22 deletions src/core/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

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

use amplify::confinement::ConfinedVec;

use super::{Site, SiteId, Status};
#[cfg(feature = "GFA")]
use crate::core::gfa::Fq;
Expand All @@ -35,7 +37,7 @@ pub const CALL_STACK_SIZE_MAX: u16 = 0xFF;

/// Registers of a single CPU/VM core.
#[derive(Clone)]
pub struct Core<Id: SiteId> {
pub struct Core<Id: SiteId, const CALL_STACK_SIZE: usize = { CALL_STACK_SIZE_MAX as usize }> {
#[cfg(feature = "GFA")]
/// Finite field order.
pub(super) fq: Fq,
Expand All @@ -51,7 +53,6 @@ pub struct Core<Id: SiteId> {
// ============================================================================================
// Arithmetic integer registers (A1024 ISA extension).

//pub(super) a128: [Option<u128>; 32],
//pub(super) a256: [Option<u256>; 32],
//pub(super) a512: [Option<u512>; 32],
//pub(super) a1024: Box<[Option<u1024>; 32]>,
Expand Down Expand Up @@ -144,10 +145,7 @@ pub struct Core<Id: SiteId> {
///
/// - [`CALL_STACK_SIZE_MAX`] constant
/// - [`Core::cp`] register
pub(super) cs: Vec<Site<Id>>,

/// Defines "top" of the call stack.
pub(super) cp: u16,
pub(super) cs: ConfinedVec<Site<Id>, 0, CALL_STACK_SIZE>,
}

/// Configuration for [`Core`] initialization.
Expand All @@ -157,8 +155,6 @@ pub struct CoreConfig {
pub halt: bool,
/// Initial value for the [`Core::cl`] flag.
pub complexity_lim: Option<u64>,
/// Size of the call stack in the [`Core::cs`] register.
pub call_stack_size: u16,
#[cfg(feature = "GFA")]
/// Order of the finite field for modulo arithmetics.
pub field_order: Fq,
Expand All @@ -168,36 +164,37 @@ impl Default for CoreConfig {
/// Sets
/// - [`CoreConfig::halt`] to `true`,
/// - [`CoreConfig::complexity_lim`] to `None`
/// - [`CoreConfig::call_stack_size`] to [`CALL_STACK_SIZE_MAX`],
/// - [`CoreConfig::field_order`] to [`Fq::F1137119`] (if `GFA` feature is set).
///
/// # See also
///
/// - [`CoreConfig::halt`]
/// - [`CoreConfig::complexity_lim`]
/// - [`CoreConfig::call_stack_size`]
/// - [`CoreConfig::field_order`]
fn default() -> Self {
CoreConfig {
halt: true,
complexity_lim: None,
call_stack_size: CALL_STACK_SIZE_MAX,
#[cfg(feature = "GFA")]
field_order: Fq::F1137119,
}
}
}

impl<Id: SiteId> Core<Id> {
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
/// Initializes registers. Sets `st0` to `true`, counters to zero, call stack to empty and the
/// rest of registers to `None` value.
///
/// An alias for [`AluCore::with`]`(`[`CoreConfig::default()`]`)`.
#[inline]
pub fn new() -> Self { Core::with(default!()) }
pub fn new() -> Self {
assert!(CALL_STACK_SIZE <= CALL_STACK_SIZE_MAX as usize, "Call stack size is too large");
Core::with(default!())
}

/// Initializes registers using a configuration object [`CoreConfig`].
pub fn with(config: CoreConfig) -> Self {
assert!(CALL_STACK_SIZE <= CALL_STACK_SIZE_MAX as usize, "Call stack size is too large");
Core {
#[cfg(feature = "GFA")]
fq: config.field_order,
Expand All @@ -216,22 +213,21 @@ impl<Id: SiteId> Core<Id> {
cy: 0,
ca: 0,
cl: config.complexity_lim,
cs: Vec::with_capacity(config.call_stack_size as usize),
cp: 0,
cs: ConfinedVec::with_capacity(CALL_STACK_SIZE),
}
}
}

/// Microcode for flag registers.
impl<Id: SiteId> Core<Id> {
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
/// Return whether check register `ck` was set to a failed state for at least once.
pub fn had_failed(&self) -> bool { self.cf == Status::Fail }

/// Return complexity limit value.
pub fn cl(&self) -> Option<u64> { return self.cl; }
pub fn cl(&self) -> Option<u64> { self.cl }
}

impl<Id: SiteId> Debug for Core<Id> {
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Debug for Core<Id, CALL_STACK_SIZE> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
let (sect, reg, val, reset) =
if f.alternate() { ("\x1B[0;4;1m", "\x1B[0;1m", "\x1B[0;32m", "\x1B[0m") } else { ("", "", "", "") };
Expand All @@ -240,18 +236,18 @@ impl<Id: SiteId> Debug for Core<Id> {
write!(f, "{reg}ch{reset} {val}{}, ", self.ch)?;
write!(f, "{reg}ck{reset} {val}{}, ", self.ck)?;
write!(f, "{reg}cf{reset} {val}{}, ", self.cf)?;
write!(f, "{reg}ct{reset} {val}{}, ", self.co)?;
write!(f, "{reg}co{reset} {val}{}, ", self.co)?;
write!(f, "{reg}cy{reset} {val}{}, ", self.cy)?;
write!(f, "{reg}ca{reset} {val}{}, ", self.ca)?;
let cl = self
.cl
.map(|v| v.to_string())
.unwrap_or_else(|| "~".to_string());
write!(f, "{reg}cl{reset} {val}{cl}, ")?;
write!(f, "{reg}cp{reset} {val}{}, ", self.cp)?;
write!(f, "{reg}cp{reset} {val}{}, ", self.cp())?;
write!(f, "\n{reg}cs{reset} {val}")?;
for p in 0..=self.cp {
write!(f, "{} ", self.cs[p as usize])?;
for item in &self.cs {
write!(f, "{} ", item)?;
}
writeln!(f)?;

Expand Down
32 changes: 31 additions & 1 deletion src/core/microcode/alu128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use core::iter;
use crate::core::{Core, IdxA, Reg, RegA, SiteId};

/// Microcode for arithmetic registers.
impl<Id: SiteId> Core<Id> {
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
pub fn get(&self, reg: Reg) -> Option<u128> {
match reg {
Reg::A(a) => match a {
Expand All @@ -52,6 +52,16 @@ impl<Id: SiteId> Core<Id> {
}
}

pub fn clr_a(&mut self, reg: RegA) -> bool {
match reg {
RegA::A8(idx) => self.clr_a8(idx),
RegA::A16(idx) => self.clr_a16(idx),
RegA::A32(idx) => self.clr_a32(idx),
RegA::A64(idx) => self.clr_a64(idx),
RegA::A128(idx) => self.clr_a128(idx),
}
}

pub fn set_a(&mut self, reg: RegA, val: u128) -> bool {
match reg {
RegA::A8(idx) => self.set_a8(idx, val as u8),
Expand All @@ -62,6 +72,26 @@ impl<Id: SiteId> Core<Id> {
}
}

pub fn take_a(&mut self, reg: RegA) -> Option<u128> {
match reg {
RegA::A8(idx) => self.take_a8(idx).map(u128::from),
RegA::A16(idx) => self.take_a16(idx).map(u128::from),
RegA::A32(idx) => self.take_a32(idx).map(u128::from),
RegA::A64(idx) => self.take_a64(idx).map(u128::from),
RegA::A128(idx) => self.take_a128(idx),
}
}

pub fn swp_a(&mut self, reg: RegA, val: u128) -> Option<u128> {
match reg {
RegA::A8(idx) => self.swp_a8(idx, val as u8).map(u128::from),
RegA::A16(idx) => self.swp_a16(idx, val as u16).map(u128::from),
RegA::A32(idx) => self.swp_a32(idx, val as u32).map(u128::from),
RegA::A64(idx) => self.swp_a64(idx, val as u64).map(u128::from),
RegA::A128(idx) => self.swp_a128(idx, val),
}
}

pub fn a8(&self, idx: IdxA) -> Option<u8> { self.a8[idx.pos()] }
pub fn a16(&self, idx: IdxA) -> Option<u16> { self.a16[idx.pos()] }
pub fn a32(&self, idx: IdxA) -> Option<u32> { self.a32[idx.pos()] }
Expand Down
19 changes: 18 additions & 1 deletion src/core/microcode/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use core::fmt::Debug;
use amplify::num::{u3, u4, u5};

use crate::core::{Core, Idx16, Idx32, SiteId, Status};
use crate::Site;

#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)]
pub enum A {
Expand Down Expand Up @@ -196,7 +197,7 @@ impl IdxA {
}

/// Microcode for flag registers.
impl<Id: SiteId> Core<Id> {
impl<Id: SiteId, const CALL_STACK_SIZE: usize> Core<Id, CALL_STACK_SIZE> {
/// Read overflow/carry flag.
pub fn co(&self) -> bool { self.co }

Expand All @@ -212,6 +213,22 @@ impl<Id: SiteId> Core<Id> {
/// Reset `ck` register.
pub fn reset_ck(&mut self) { self.ck = Status::Ok }

/// Return size of the call stack.
pub fn cp(&self) -> u16 { self.cs.len() as u16 }

/// Push a location to a call stack.
///
/// # Returns
///
/// Top of the call stack.
pub fn push_cs(&mut self, from: Site<Id>) -> Option<u16> {
self.cs.push(from).ok()?;
Some(self.cp())
}

/// Pops a call stack item.
pub fn pop_cs(&mut self) -> Option<Site<Id>> { self.cs.pop() }

/// Accumulate complexity value.
///
/// # Returns
Expand Down
2 changes: 1 addition & 1 deletion src/core/microcode/gfa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub enum Fq {
F1137119,
#[display("F1289", alt = "2^128-9")]
F1289,
#[display("{0:x}.h")]
#[display("{0:X}:h")]
Other(u128),
}

Expand Down
4 changes: 2 additions & 2 deletions src/core/regs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl<Id: SiteId> Site<Id> {
}

impl<Id: SiteId> Display for Site<Id> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}:{:04X}.h", self.prog_id, self.offset) }
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}@{:04X}:h", self.prog_id, self.offset) }
}

#[allow(dead_code)]
Expand Down Expand Up @@ -178,7 +178,7 @@ pub(super) enum Idx32 {

#[display(".g")]
Sg = 0x10,
#[display(".h")]
#[display(":h")]
Sh = 0x11,
#[display(".k")]
Sk = 0x12,
Expand Down
Loading

0 comments on commit b170f5f

Please sign in to comment.