Skip to content

Commit

Permalink
Finish implementing PointerBits for 32 bit.
Browse files Browse the repository at this point in the history
I can't easily test this on my own machine, but I think it'll work.
  • Loading branch information
kevinhartman committed Dec 17, 2024
1 parent f520d63 commit cb79fe2
Showing 1 changed file with 30 additions and 23 deletions.
53 changes: 30 additions & 23 deletions crates/circuit/src/packed_instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,20 +288,39 @@ impl ImmediateValue {
}
}

#[cfg(target_pointer_width = "64")]
#[bitfield(u64, new = false)]
struct PointerBits {
#[bits(3, access = RO)]
discriminant: PackedOperationType,
#[bits(61, from = address_from_u64, into = u64_from_address)]
address: u64,
#[bits(61, from = PointerBits::unpack_address, into = PointerBits::pack_address)]
address: usize,
}

const fn address_from_u64(value: u64) -> u64 {
value << 3
// On a 64-bit system, we tell the bitfield-struct crate to use these when reading and writing the
// address, since the lower 3 bits contain our discriminant.
#[cfg(target_pointer_width = "64")]
impl PointerBits {
const fn unpack_address(value: usize) -> usize {
value << 3
}

const fn pack_address(value: usize) -> usize {
value >> 3
}
}

const fn u64_from_address(value: u64) -> u64 {
value >> 3
#[cfg(target_pointer_width = "32")]
#[bitfield(u64, new = false)]
struct PointerBits {
#[bits(3, access = RO)]
discriminant: PackedOperationType,
// The padding here is used to get the address aligned to a word to give the compiler the best
// chance at optimizing-out the bit shift needed to read it from this bitfield.
#[bits(29)]
__: u32,
#[bits(32)]
address: usize,
}

impl PointerBits {
Expand All @@ -325,28 +344,16 @@ impl PointerBits {
}

#[inline]
#[allow(clippy::assertions_on_constants)]
fn with_pointer(self, value: NonNull<()>) -> Self {
let addr = value.as_ptr() as u64;
assert_eq!(addr & BitField::DISCRIMINANT_MASK, 0);
let addr = value.as_ptr() as usize;
assert!(
cfg!(target_pointer_width = "32") || (addr as u64 & BitField::DISCRIMINANT_MASK == 0)
);
self.with_address(addr)
}
}

#[cfg(target_pointer_width = "32")]
impl OpBitField {
#[inline]
unsafe fn pointer(&self) -> NonNull<()> {
let ptr = self.payload().u32 as *mut ();
NonNull::new_unchecked(ptr)
}

#[inline]
unsafe fn with_pointer(self, value: NonNull<()>) -> Self {
let addr = value.as_ptr() as u32;
self.with_payload(OpPayload { u32: addr })
}
}

impl PackedOperation {
/// Get the contained `StandardGate`.
///
Expand Down

0 comments on commit cb79fe2

Please sign in to comment.