Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eliza/bit misc #292

Merged
merged 3 commits into from
Aug 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions bitfield/src/bitfield.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
/// # Generated Implementations
///
/// The `bitfield!` macro generates a type with the following functions, where
/// `T` is the integer type that represents the bitfield (one of `u8`, `u16`,
/// `u32`, `u64`, or `usize`):
/// `{int}` is the integer type that represents the bitfield (one of `u8`,
/// `u16`,`u32`, `u64`, or `usize`):
///
/// | Function | Description |
/// |:--|:--|
/// | `fn new() -> Self` | Returns a new instance of the bitfield type with all bits zeroed. |
/// | `fn from_bits(bits: T) -> Self` | Converts a `T` into an instance of the bitfield type. |
/// | `const fn new() -> Self` | Returns a new instance of the bitfield type with all bits zeroed. |
/// | `const fn from_bits(bits: {int}) -> Self` | Converts an `{int}` into an instance of the bitfield type. |
/// | `const fn bits(self) -> {int}` | Returns this bitfield's bits as a raw integer value. |
/// | `fn with<U>(self, packer: Self::Packer<U>, value: U) -> Self` | Given one of this type's generated packing specs for a `U`-typed value, and a `U`-typed value, returns a new instance of `Self` with the bit representation of `value` packed into the range represented by `packer`. |
/// | `fn set<U>(&mut self, packer: Self::Packer<U>, value: U) -> &mut Self` | Similar to `with`, except `self` is mutated in place, rather than returning a new instance of `Self`. |
/// | `fn get<U>(&self, packer: Self::Packer<U>) -> U` | Given one of this type's generated packing specs for a `U`-typed value, unpacks the bit range represented by that value as a `U` and returns it. This method panics if the requested bit range does not contain a valid bit pattern for a `U`-typed value, as determined by `U`'s implementation of the [`FromBits`] trait. |
Expand All @@ -43,9 +44,12 @@
/// |:--|:--|
/// | [`fmt::Debug`] | The `Debug` implementation prints the bitfield as a "struct", with a "field" for each packing spec in the bitfield. If any of the bitfield's packing specs pack typed values, that type's [`fmt::Debug`] implementation is used rather than printing the value as an integer. |
/// | [`fmt::Binary`] | Prints the raw bits of this bitfield as a binary number. |
/// | [`fmt::UpperHex`] and [`fmt::LowerHex`] | Prints the raw bits of this bitfield in hexadecimal. |
/// | [`fmt::Display`] | Pretty-prints the bitfield in a very nice-looking multi-line format which I'm rather proud of. See [here](#example-display-output) for examples of this format. |
/// | [`Copy`] | Behaves identically as the [`Copy`] implementation for the underlying integer type. |
/// | [`Clone`] | Behaves identically as the [`Clone`] implementation for the underlying integer type. |
/// | [`From`]`<{int}> for Self` | Converts a raw integer value into an instance of the bitfield type. This is equivalent to calling the bitfield type's `from_bits` function. |
/// | [`From`]`<Self> for {int}` | Converts an instance of the bitfield type into a raw integer value. This is equivalent to calling the bitfield type's `bits` method. |
///
/// Additional traits may be derived for the bitfield type, such as
/// [`PartialEq`], [`Eq`], and [`Default`]. These traits are not automatically
Expand Down Expand Up @@ -259,6 +263,8 @@
/// [`fmt::Debug`]: core::fmt::Debug
/// [`fmt::Display`]: core::fmt::Display
/// [`fmt::Binary`]: core::fmt::Binary
/// [`fmt::UpperHex`]: core::fmt::UpperHex
/// [`fmt::LowerHex`]: core::fmt::LowerHex
/// [transparent]: https://doc.rust-lang.org/reference/type-layout.html#the-transparent-representation
/// [`example`]: crate::example
/// [`ExampleBitfield`]: crate::example::ExampleBitfield
Expand Down Expand Up @@ -308,15 +314,25 @@ macro_rules! bitfield {
),+];

/// Constructs a new instance of `Self` from the provided raw bits.
#[inline]
#[must_use]
$vis const fn from_bits(bits: $T) -> Self {
Self(bits)
}

/// Constructs a new instance of `Self` with all bits set to 0.
#[inline]
#[must_use]
$vis const fn new() -> Self {
Self(0)
}

/// Returns the raw bit representatiion of `self` as an integer.
#[inline]
$vis const fn bits(self) -> $T {
self.0
}

/// Packs the bit representation of `value` into `self` at the bit
/// range designated by `field`, returning a new bitfield.
$vis fn with<T>(self, field: $crate::bitfield! { @t $T, T, Self }, value: T) -> Self
Expand Down Expand Up @@ -482,12 +498,50 @@ macro_rules! bitfield {
impl core::fmt::Binary for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:#b}", self)).finish()
write!(f, concat!(stringify!($Name), "({:#b})"), self.0)
} else {
write!(f, concat!(stringify!($Name), "({:b})"), self.0)
}
}
}

#[automatically_derived]
impl core::fmt::UpperHex for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
write!(f, concat!(stringify!($Name), "({:#X})"), self.0)
} else {
write!(f, concat!(stringify!($Name), "({:X})"), self.0)
}
}
}

#[automatically_derived]
impl core::fmt::LowerHex for $Name {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if f.alternate() {
write!(f, concat!(stringify!($Name), "({:#x})"), self.0)
} else {
f.debug_tuple(stringify!($Name)).field(&format_args!("{:b}", self)).finish()
write!(f, concat!(stringify!($Name), "({:x})"), self.0)
}
}
}

#[automatically_derived]
impl From<$T> for $Name {
#[inline]
fn from(val: $T) -> Self {
Self::from_bits(val)
}
}

#[automatically_derived]
impl From<$Name> for $T {
#[inline]
fn from($Name(bits): $Name) -> Self {
bits
}
}
};
(@field<$T:ident>, prev: $Prev:ident:
$(#[$meta:meta])*
Expand Down
36 changes: 0 additions & 36 deletions hal-x86_64/src/interrupt/idt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,42 +214,6 @@ impl Attrs {
}
}

// impl fmt::Debug for Attrs {
// fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
// f.debug_struct("Attrs")
// .field("gate_kind", &self.gate_kind())
// .field("ring", &self.ring())
// .field("is_32_bit", &self.is_32_bit())
// .field("is_present", &self.is_present())
// .field("bits", &format_args!("{:b}", self))
// .finish()
// }
// }

// impl fmt::Binary for Attrs {
// fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
// f.debug_tuple("Attrs")
// .field(&format_args!("{:#08b}", self.0))
// .finish()
// }
// }

impl fmt::UpperHex for Attrs {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Attrs")
.field(&format_args!("{:#X}", self.0))
.finish()
}
}

impl fmt::LowerHex for Attrs {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Attrs")
.field(&format_args!("{:#x}", self.0))
.finish()
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
33 changes: 1 addition & 32 deletions hal-x86_64/src/segment.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::cpu;
use core::{arch::asm, fmt};
use core::arch::asm;
/// Returns the current code segment selector in `%cs`.
pub fn code_segment() -> Selector {
let value: u16;
Expand Down Expand Up @@ -85,37 +85,6 @@ impl Selector {
Self::INDEX.pack_into(index, &mut self.0);
self
}

pub fn bits(&self) -> u16 {
self.0
}
}

// impl fmt::Debug for Selector {
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// f.debug_struct("segment::Selector")
// .field("ring", &self.ring())
// .field("index", &self.index())
// .field("is_gdt", &self.is_gdt())
// .field("bits", &format_args!("{:#b}", self.0))
// .finish()
// }
// }

impl fmt::UpperHex for Selector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("segment::Selector")
.field(&format_args!("{:#X}", self.0))
.finish()
}
}

impl fmt::LowerHex for Selector {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("segment::Selector")
.field(&format_args!("{:#x}", self.0))
.finish()
}
}

#[cfg(test)]
Expand Down