From 856742ac5a254138f884b529e238834c90b806e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20Kr=C3=BCger?= Date: Thu, 10 Oct 2024 17:11:44 +0100 Subject: [PATCH] RISC-V: Remove EnumCell --- .../csregisters/values/mstatus.rs | 40 +++--- .../src/machine_state/csregisters/xstatus.rs | 8 +- src/riscv/lib/src/ocaml_api.rs | 57 ++++++-- src/riscv/lib/src/pvm/common.rs | 46 +++---- src/riscv/lib/src/state_backend.rs | 2 - src/riscv/lib/src/state_backend/enums.rs | 126 ------------------ src/riscv/lib/src/state_backend/layout.rs | 2 +- src/riscv/lib/tests/expected/jstz/state_hash | 2 +- 8 files changed, 87 insertions(+), 196 deletions(-) delete mode 100644 src/riscv/lib/src/state_backend/enums.rs diff --git a/src/riscv/lib/src/machine_state/csregisters/values/mstatus.rs b/src/riscv/lib/src/machine_state/csregisters/values/mstatus.rs index 24aaf742ab08..5c5371660cfe 100644 --- a/src/riscv/lib/src/machine_state/csregisters/values/mstatus.rs +++ b/src/riscv/lib/src/machine_state/csregisters/values/mstatus.rs @@ -10,8 +10,8 @@ use crate::{ xstatus::{ExtensionValue, MPPValue, MStatus, SPPValue, XLenValue}, }, state_backend::{ - AllocatedOf, Atom, Cell, EffectCell, EnumCell, EnumCellLayout, ManagerBase, ManagerClone, - ManagerRead, ManagerReadWrite, ManagerWrite, Ref, + AllocatedOf, Atom, Cell, EffectCell, ManagerBase, ManagerClone, ManagerRead, + ManagerReadWrite, ManagerWrite, Ref, }, struct_layout, }; @@ -28,10 +28,10 @@ pub struct MStatusValue { pub spie: Cell, pub ube: Cell, pub mpie: Cell, - pub spp: EnumCell, - pub mpp: EnumCell, - pub fs: EnumCell, - pub xs: EnumCell, + pub spp: Cell, + pub mpp: Cell, + pub fs: Cell, + pub xs: Cell, // vs is always OFF as we do not support the virtualisation extension pub mprv: Cell, pub sum: Cell, @@ -39,8 +39,8 @@ pub struct MStatusValue { pub tvm: Cell, pub tw: Cell, pub tsr: Cell, - pub uxl: EnumCell, - pub sxl: EnumCell, + pub uxl: Cell, + pub sxl: Cell, pub sbe: Cell, pub mbe: Cell, } @@ -53,18 +53,18 @@ impl MStatusValue { spie: space.spie, ube: space.ube, mpie: space.mpie, - spp: EnumCell::bind(space.spp), - mpp: EnumCell::bind(space.mpp), - fs: EnumCell::bind(space.fs), - xs: EnumCell::bind(space.xs), + spp: space.spp, + mpp: space.mpp, + fs: space.fs, + xs: space.xs, mprv: space.mprv, sum: space.sum, mxr: space.mxr, tvm: space.tvm, tw: space.tw, tsr: space.tsr, - uxl: EnumCell::bind(space.uxl), - sxl: EnumCell::bind(space.sxl), + uxl: space.uxl, + sxl: space.sxl, sbe: space.sbe, mbe: space.mbe, } @@ -129,18 +129,18 @@ struct_layout!( spie: Atom, ube: Atom, mpie: Atom, - spp: EnumCellLayout, - mpp: EnumCellLayout, - fs: EnumCellLayout, - xs: EnumCellLayout, + spp: Atom, + mpp: Atom, + fs: Atom, + xs: Atom, mprv: Atom, sum: Atom, mxr: Atom, tvm: Atom, tw: Atom, tsr: Atom, - uxl: EnumCellLayout, - sxl: EnumCellLayout, + uxl: Atom, + sxl: Atom, sbe: Atom, mbe: Atom, } diff --git a/src/riscv/lib/src/machine_state/csregisters/xstatus.rs b/src/riscv/lib/src/machine_state/csregisters/xstatus.rs index 8915de734c66..b5fba4fe730d 100644 --- a/src/riscv/lib/src/machine_state/csregisters/xstatus.rs +++ b/src/riscv/lib/src/machine_state/csregisters/xstatus.rs @@ -19,7 +19,7 @@ use crate::{ machine_state::mode::Mode, }; -#[derive(PartialEq, Clone, Copy, Debug, Default)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] #[repr(u8)] pub enum MPPValue { User = 0b00, @@ -68,7 +68,7 @@ impl Bits64 for MPPValue { } } -#[derive(PartialEq, Clone, Copy, Debug, Default)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] #[repr(u8)] pub enum SPPValue { User = 0b0, @@ -104,7 +104,7 @@ impl Bits64 for SPPValue { } } -#[derive(PartialEq, Clone, Copy, Debug, Default)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] #[repr(u64)] pub enum XLenValue { #[default] @@ -137,7 +137,7 @@ impl Bits64 for XLenValue { } } -#[derive(PartialEq, Clone, Copy, Debug, Default)] +#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, serde::Serialize, serde::Deserialize)] #[repr(u64)] pub enum ExtensionValue { Off = 0b00, diff --git a/src/riscv/lib/src/ocaml_api.rs b/src/riscv/lib/src/ocaml_api.rs index 2ecce271d67c..cb77c7edc0fe 100644 --- a/src/riscv/lib/src/ocaml_api.rs +++ b/src/riscv/lib/src/ocaml_api.rs @@ -37,7 +37,7 @@ pub struct Id(storage::Hash); ocaml::custom!(Repo); ocaml::custom!(Id); -#[derive(ocaml::FromValue, ocaml::ToValue, IntoPrimitive, TryFromPrimitive)] +#[derive(ocaml::FromValue, ocaml::ToValue, IntoPrimitive, TryFromPrimitive, strum::EnumCount)] #[ocaml::sig("Evaluating | WaitingForInput | WaitingForMetadata")] #[repr(u8)] pub enum Status { @@ -46,6 +46,49 @@ pub enum Status { WaitingForMetadata, } +// Check that [`PvmStatus`] and [`Status`] can be coerced into each other. +const STATUS_ENUM_COERCIBLE: bool = { + if ::COUNT != ::COUNT + || ::COUNT != 3 + { + panic!("Not coercible!"); + } + + if PvmStatus::Evaluating as u8 != Status::Evaluating as u8 { + panic!("Not coercible!"); + } + + if PvmStatus::WaitingForInput as u8 != Status::WaitingForInput as u8 { + panic!("Not coercible!"); + } + + if PvmStatus::WaitingForMetadata as u8 != Status::WaitingForMetadata as u8 { + panic!("Not coercible!"); + } + + true +}; + +impl From for Status { + fn from(item: PvmStatus) -> Self { + if STATUS_ENUM_COERCIBLE { + unsafe { std::mem::transmute(item) } + } else { + unreachable!() + } + } +} + +impl From for PvmStatus { + fn from(item: Status) -> Self { + if STATUS_ENUM_COERCIBLE { + unsafe { std::mem::transmute(item) } + } else { + unreachable!() + } + } +} + #[derive(ocaml::FromValue, ocaml::ToValue)] #[ocaml::sig("RawData of string | Metadata of bytes * int32")] pub enum RevealData<'a> { @@ -67,18 +110,6 @@ pub struct InputRequest; ocaml::custom!(InputRequest); -impl From for Status { - fn from(item: PvmStatus) -> Self { - Status::try_from(item as u8).expect("Invalid conversion") - } -} - -impl From for PvmStatus { - fn from(item: Status) -> Self { - PvmStatus::from(item as u8) - } -} - impl<'a> PvmHooks<'a> { fn from_printer(printer: ocaml::Value, gc: &'a ocaml::Runtime) -> PvmHooks<'a> { let putchar = move |c: u8| unsafe { diff --git a/src/riscv/lib/src/pvm/common.rs b/src/riscv/lib/src/pvm/common.rs index 1524ef676837..e60f66df4482 100644 --- a/src/riscv/lib/src/pvm/common.rs +++ b/src/riscv/lib/src/pvm/common.rs @@ -5,7 +5,7 @@ use crate::{ machine_state::{self, bus::main_memory}, pvm::sbi, - state_backend::{self, EnumCell, EnumCellLayout}, + state_backend::{self, Atom, Cell}, traps::EnvironException, }; use std::{ @@ -54,11 +54,22 @@ impl<'a> Default for PvmHooks<'a> { pub type PvmLayout = ( state_backend::Atom, machine_state::MachineStateLayout, - EnumCellLayout, + Atom, ); /// PVM status -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + PartialOrd, + Ord, + serde::Serialize, + serde::Deserialize, + strum::EnumCount, +)] #[repr(u8)] pub enum PvmStatus { Evaluating, @@ -84,29 +95,6 @@ impl fmt::Display for PvmStatus { } } -impl From for PvmStatus { - #[inline(always)] - fn from(value: u8) -> Self { - const EVALUATING: u8 = PvmStatus::Evaluating as u8; - const WAITING_FOR_INPUT: u8 = PvmStatus::WaitingForInput as u8; - const WAITING_FOR_METADATA: u8 = PvmStatus::WaitingForMetadata as u8; - - match value { - EVALUATING => Self::Evaluating, - WAITING_FOR_INPUT => Self::WaitingForInput, - WAITING_FOR_METADATA => Self::WaitingForMetadata, - _ => Self::default(), - } - } -} - -impl From for u8 { - #[inline(always)] - fn from(value: PvmStatus) -> Self { - value as u8 - } -} - /// Value for the initial version const INITIAL_VERSION: u64 = 0; @@ -118,7 +106,7 @@ pub struct Pvm< > { version: state_backend::Cell, pub(crate) machine_state: machine_state::MachineState, - status: EnumCell, + status: Cell, } impl< @@ -132,7 +120,7 @@ impl< Self { version: space.0, machine_state: machine_state::MachineState::bind(space.1), - status: EnumCell::bind(space.2), + status: space.2, } } @@ -154,7 +142,7 @@ impl< { self.version.write(INITIAL_VERSION); self.machine_state.reset(); - self.status.reset(); + self.status.write(PvmStatus::default()); } /// Handle an exception using the defined Execution Environment. diff --git a/src/riscv/lib/src/state_backend.rs b/src/riscv/lib/src/state_backend.rs index 545ab5502625..6eea0aa0380e 100644 --- a/src/riscv/lib/src/state_backend.rs +++ b/src/riscv/lib/src/state_backend.rs @@ -57,7 +57,6 @@ mod effects; mod elems; -mod enums; pub mod hash; mod layout; pub mod owned_backend; @@ -66,7 +65,6 @@ mod region; pub use effects::*; pub use elems::*; -pub use enums::*; pub use layout::*; pub use region::*; diff --git a/src/riscv/lib/src/state_backend/enums.rs b/src/riscv/lib/src/state_backend/enums.rs deleted file mode 100644 index 74cf6d1d0502..000000000000 --- a/src/riscv/lib/src/state_backend/enums.rs +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-FileCopyrightText: 2024 TriliTech -// -// SPDX-License-Identifier: MIT - -use super::{ - AllocatedOf, Atom, Cell, CellBase, CellRead, CellReadWrite, CellWrite, Elem, ManagerBase, - ManagerClone, ManagerRead, ManagerReadWrite, ManagerWrite, Ref, -}; -use std::marker::PhantomData; - -/// Cell representing an enumeration type -pub struct EnumCell { - cell: Cell, - _pd: PhantomData, -} - -/// Layout of an enum cell -pub type EnumCellLayout = Atom; - -impl EnumCell -where - T: From + Default, - R: From + Elem, - M: ManagerBase, -{ - /// Bind the enum cell to the allocated space. - pub fn bind(space: AllocatedOf, M>) -> Self { - Self { - cell: space, - _pd: PhantomData, - } - } - - /// Obtain a structure with references to the bound regions of this type. - pub fn struct_ref(&self) -> AllocatedOf, Ref<'_, M>> { - self.cell.struct_ref() - } - - /// Reset the enum cell by writing the default value of `T`. - pub fn reset(&mut self) - where - M: ManagerWrite, - { - self.write(T::default()); - } - - /// Write a value to the enum cell. - pub fn write(&mut self, value: T) - where - M: ManagerWrite, - { - self.cell.write(value.into()); - } - - /// Replace a value in the enum cell, returning the old value. - pub fn replace(&mut self, value: T) -> T - where - M: ManagerReadWrite, - { - T::from(self.cell.replace(value.into())) - } - - /// Read the value from the enum cell. - pub fn read(&self) -> T - where - M: ManagerRead, - { - T::from(self.cell.read()) - } -} - -impl Clone for EnumCell -where - T: From + Default, - R: From + Elem, - M: ManagerClone, -{ - fn clone(&self) -> Self { - Self { - cell: self.cell.clone(), - _pd: PhantomData, - } - } -} - -impl CellBase for EnumCell -where - R: Elem, - M: ManagerBase, -{ - type Value = T; -} - -impl CellRead for EnumCell -where - T: From + Default, - R: From + Elem, - M: ManagerRead, -{ - fn read(&self) -> Self::Value { - EnumCell::read(self) - } -} - -impl CellWrite for EnumCell -where - T: From + Default, - R: From + Elem, - M: ManagerWrite, -{ - fn write(&mut self, value: Self::Value) { - EnumCell::write(self, value) - } -} - -impl CellReadWrite for EnumCell -where - T: From + Default, - R: From + Elem, - M: ManagerReadWrite, -{ - #[inline(always)] - fn replace(&mut self, value: Self::Value) -> Self::Value { - EnumCell::replace(self, value) - } -} diff --git a/src/riscv/lib/src/state_backend/layout.rs b/src/riscv/lib/src/state_backend/layout.rs index a3b6523212ef..cc21c1327648 100644 --- a/src/riscv/lib/src/state_backend/layout.rs +++ b/src/riscv/lib/src/state_backend/layout.rs @@ -63,7 +63,7 @@ impl Layout for Array { /// struct_layout!( /// pub struct ExampleLayout { /// satp_ppn: Atom, -/// mode: EnumCellLayout, +/// mode: Atom, /// cached: Atom, /// } /// ); diff --git a/src/riscv/lib/tests/expected/jstz/state_hash b/src/riscv/lib/tests/expected/jstz/state_hash index aa1e7b2b6c8f..09a2d6578272 100644 --- a/src/riscv/lib/tests/expected/jstz/state_hash +++ b/src/riscv/lib/tests/expected/jstz/state_hash @@ -1 +1 @@ -Hash { digest: [35, 234, 12, 16, 167, 241, 148, 107, 101, 41, 114, 198, 97, 176, 82, 143, 138, 108, 153, 152, 165, 112, 30, 4, 221, 215, 159, 63, 76, 170, 60, 111] } +Hash { digest: [56, 187, 114, 80, 35, 29, 229, 166, 35, 161, 182, 103, 51, 112, 65, 109, 123, 125, 148, 114, 66, 241, 255, 2, 170, 66, 30, 42, 75, 189, 108, 151] } -- GitLab