Skip to content

Commit

Permalink
add assign from u64 and i64 to mutable bv ops
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Sep 16, 2024
1 parent 8c6cb00 commit e8cde56
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "baa"
version = "0.7.3"
version = "0.7.4"
edition = "2021"
authors = ["Kevin Laeufer <[email protected]>"]
description = "BitVector and Array Arithmetic"
Expand Down
60 changes: 60 additions & 0 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,66 @@ pub trait BitVecMutOps: BitVecOps {
});
self.mask_msb();
}

fn assign_from_u64(&mut self, value: u64) {
debug_assert_eq!(Word::BITS, u64::BITS, "basic assumption of this function");
// clear all words
self.clear();
// assign lsb
self.words_mut()[0] = value;
// make sure the value agrees with the bit width
self.mask_msb();
debug_assert_eq!(
self.words()[0],
value,
"value {value} does not fit into {} bits",
self.width()
);
}

fn assign_from_i64(&mut self, value: i64) {
debug_assert_eq!(Word::BITS, i64::BITS, "basic assumption of this function");
let width = self.width();
// clear all words
self.clear();
// assign lsb and sign extend if necessary
if self.words().len() == 1 {
let masked = value as u64 & crate::arithmetic::mask(width);
self.words_mut()[0] = masked;
} else {
crate::arithmetic::sign_extend(self.words_mut(), &[value as u64], u64::BITS, width);
};

#[cfg(debug_assertions)]
if self.is_negative() {
if self.width() < Word::BITS {
let extra_sign_bits =
crate::arithmetic::mask(Word::BITS - self.width()) << self.width();
let word_0 = self.words()[0];
let word_0_with_bits = word_0 | extra_sign_bits;
debug_assert_eq!(
word_0_with_bits,
value as u64,
"value {value} does not fit into {} bits",
self.width()
);
} else {
debug_assert_eq!(
self.words()[0],
value as u64,
"value {value} does not fit into {} bits",
self.width()
);
}
} else {
debug_assert_eq!(
self.words()[0],
value as u64,
"value {value} does not fit into {} bits",
self.width()
);
}
}
}

pub const DENSE_ARRAY_MAX_INDEX_WIDTH: WidthInt = 48;
Expand Down
58 changes: 6 additions & 52 deletions src/value/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,61 +29,15 @@ impl BitVecValue {
}

pub fn from_u64(value: u64, width: WidthInt) -> Self {
debug_assert_eq!(Word::BITS, u64::BITS, "basic assumption of this function");
let num_words = width.div_ceil(Word::BITS) as usize;
debug_assert!(num_words >= 1, "cannot create a zero bit value!");
let mut words = SmallVec::with_capacity(num_words);
words.push(value);
// add zeros if necessary
for _ in 1..num_words {
words.push(0);
}
crate::arithmetic::mask_msb(&mut words, width);
debug_assert_eq!(
words[0], value,
"value {value} does not fit into {width} bits"
);

Self { width, words }
let mut out = Self::zero(width);
out.assign_from_u64(value);
out
}

pub fn from_i64(value: i64, width: WidthInt) -> Self {
debug_assert_eq!(Word::BITS, u64::BITS, "basic assumption of this function");
let num_words = width.div_ceil(Word::BITS) as usize;
debug_assert!(num_words >= 1, "cannot create a zero bit value!");
let words = if num_words == 1 {
let masked = value as u64 & crate::arithmetic::mask(width);
smallvec![masked]
} else {
let mut words = smallvec![0; num_words];
crate::arithmetic::sign_extend(&mut words, &[value as u64], u64::BITS, width);
words
};

#[cfg(debug_assertions)]
if crate::arithmetic::is_neg(&words, width) {
if width < Word::BITS {
let extra_sign_bits = crate::arithmetic::mask(Word::BITS - width) << width;
let word_0 = words[0];
let word_0_with_bits = word_0 | extra_sign_bits;
debug_assert_eq!(
word_0_with_bits, value as u64,
"value {value} does not fit into {width} bits"
);
} else {
debug_assert_eq!(
words[0], value as u64,
"value {value} does not fit into {width} bits"
);
}
} else {
debug_assert_eq!(
words[0], value as u64,
"value {value} does not fit into {width} bits"
);
}

Self { width, words }
let mut out = Self::zero(width);
out.assign_from_i64(value);
out
}

pub fn from_bool(value: bool) -> Self {
Expand Down

0 comments on commit e8cde56

Please sign in to comment.