diff --git a/crates/fayalite/src/expr/ops.rs b/crates/fayalite/src/expr/ops.rs index 0c8c4fa..15c195e 100644 --- a/crates/fayalite/src/expr/ops.rs +++ b/crates/fayalite/src/expr/ops.rs @@ -265,7 +265,7 @@ impl Neg { }; let result_ty = retval.ty(); retval.literal_bits = arg.to_literal_bits().map(|bits| { - Intern::intern_owned(result_ty.bits_from_bigint_wrapping(-SInt::bits_to_bigint(&bits))) + Intern::intern_owned(result_ty.bits_from_bigint_wrapping(&-SInt::bits_to_bigint(&bits))) }); retval } @@ -372,7 +372,7 @@ fn binary_op_literal_bits BitVec { + pub fn bits_from_bigint_wrapping(self, v: &BigInt) -> BitVec { BoolOrIntType::bits_from_bigint_wrapping(self, v) } - pub fn from_bigint_wrapping(self, v: BigInt) -> $value { + pub fn from_bigint_wrapping(self, v: &BigInt) -> $value { $value { bits: Arc::new(self.bits_from_bigint_wrapping(v)), _phantom: PhantomData, } } pub fn from_int_wrapping(self, v: impl Into) -> $value { - self.from_bigint_wrapping(v.into()) + self.from_bigint_wrapping(&v.into()) } pub fn zero(self) -> $value { self.from_int_wrapping(0u8) @@ -234,7 +234,7 @@ macro_rules! impl_int { fn new(width: Width::SizeType) -> Self { $name { width } } - fn value_from_bigint_wrapping(self, v: BigInt) -> Self::Value { + fn value_from_bigint_wrapping(self, v: &BigInt) -> Self::Value { $value::::from_bigint_wrapping(self, v) } fn bits_to_value(bits: Cow<'_, BitSlice>) -> Self::Value { @@ -378,7 +378,7 @@ macro_rules! impl_int { self.bits.len() } } - pub fn from_bigint_wrapping(ty: $name, v: BigInt) -> $value { + pub fn from_bigint_wrapping(ty: $name, v: &BigInt) -> $value { ty.from_bigint_wrapping(v) } pub fn to_bigint(&self) -> BigInt { @@ -603,20 +603,23 @@ pub trait BoolOrIntType: Type + sealed::BoolOrIntTypeSealed { UIntType::new(Self::Width::from_usize(self.width())) } fn value_from_int_wrapping(self, v: impl Into) -> Self::Value { - self.value_from_bigint_wrapping(v.into()) + self.value_from_bigint_wrapping(&v.into()) } - fn value_from_bigint_wrapping(self, v: BigInt) -> Self::Value; - fn bits_from_bigint_wrapping(self, v: BigInt) -> BitVec { - let width = self.width(); + fn value_from_bigint_wrapping(self, v: &BigInt) -> Self::Value; + fn bits_from_bigint_wrapping(self, v: &BigInt) -> BitVec { + let mut bits = BitVec::repeat(false, self.width()); + Self::copy_bits_from_bigint_wrapping(v, &mut bits); + bits + } + fn copy_bits_from_bigint_wrapping(v: &BigInt, bits: &mut BitSlice) { + let width = bits.len(); let mut bytes = v.to_signed_bytes_le(); bytes.resize( width.div_ceil(u8::BITS as usize), if v.is_negative() { 0xFF } else { 0 }, ); let bitslice = &BitSlice::::from_slice(&bytes)[..width]; - let mut bits = BitVec::new(); - bits.extend_from_bitslice(bitslice); - bits + bits.clone_from_bitslice(bitslice); } fn bits_to_bigint(bits: &BitSlice) -> BigInt { let sign_byte = if Self::Signed::VALUE && bits.last().as_deref().copied().unwrap_or(false) { @@ -712,7 +715,7 @@ impl BoolOrIntType for Bool { Bool } - fn value_from_bigint_wrapping(self, v: BigInt) -> Self::Value { + fn value_from_bigint_wrapping(self, v: &BigInt) -> Self::Value { v.bit(0) }