Skip to content

Commit

Permalink
Implemented division and remainder
Browse files Browse the repository at this point in the history
  • Loading branch information
haxelion committed Jul 7, 2024
1 parent d11f0bf commit 13d4c9a
Show file tree
Hide file tree
Showing 7 changed files with 831 additions and 39 deletions.
51 changes: 44 additions & 7 deletions src/auto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use std::cmp::Ordering;
use std::fmt::{Binary, Display, LowerHex, Octal, UpperHex};

use std::ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Mul, MulAssign,
Not, Range, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Not, Range, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
};

use crate::dynamic::BVD;
Expand All @@ -26,11 +26,11 @@ use crate::{BitVector, ConvertionError, Endianness};

// Choose a fixed BVF type which should match the size of BVD inside the enum
#[cfg(target_pointer_width = "16")]
type BVP = BV32;
pub(crate) type BVP = BV32;
#[cfg(target_pointer_width = "32")]
type BVP = BV64;
pub(crate) type BVP = BV64;
#[cfg(target_pointer_width = "64")]
type BVP = BV128;
pub(crate) type BVP = BV128;

// ------------------------------------------------------------------------------------------------
// Bit Vector automatic allocation implementation
Expand Down Expand Up @@ -332,6 +332,33 @@ impl BitVector for BV {
BV::Dynamic(b) => b.is_zero(),
}
}

fn div_rem<B: BitVector>(&self, divisor: &B) -> (Self, Self)
where
Self: for<'a> TryFrom<&'a B, Error: std::fmt::Debug>,
{
assert!(!divisor.is_zero(), "Division by zero");
let mut quotient = BV::zeros(self.len());
let mut rem = self.clone();
if divisor.significant_bits() > self.significant_bits() {
return (quotient, rem);
}

let shift = self.significant_bits() - divisor.significant_bits();
let mut divisor: BV = divisor.try_into().expect("should never fail");
divisor.resize(self.len(), Bit::Zero);
divisor <<= shift;

for i in (0..shift + 1).rev() {
if rem >= divisor {
rem -= &divisor;
quotient.set(i, Bit::One);
}
divisor >>= 1u32;
}

(quotient, rem)
}
}

// ------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -683,7 +710,10 @@ macro_rules! impl_op_assign {
}
}

impl<I: Integer, const N: usize> $trait<&BVF<I, N>> for BV {
impl<I: Integer, const N: usize> $trait<&BVF<I, N>> for BV
where
u64: StaticCast<I>,
{
fn $method(&mut self, bvf: &BVF<I, N>) {
match self {
BV::Fixed(b) => b.$method(bvf),
Expand All @@ -692,7 +722,10 @@ macro_rules! impl_op_assign {
}
}

impl<I: Integer, const N: usize> $trait<BVF<I, N>> for BV {
impl<I: Integer, const N: usize> $trait<BVF<I, N>> for BV
where
u64: StaticCast<I>,
{
fn $method(&mut self, bvf: BVF<I, N>) {
match self {
BV::Fixed(b) => b.$method(bvf),
Expand Down Expand Up @@ -727,6 +760,8 @@ impl_op_assign!(BitXorAssign, bitxor_assign);
impl_op_assign!(AddAssign, add_assign);
impl_op_assign!(SubAssign, sub_assign);
impl_op_assign!(MulAssign, mul_assign);
impl_op_assign!(DivAssign, div_assign);
impl_op_assign!(RemAssign, rem_assign);

macro_rules! impl_op {
($trait:ident, $method:ident, $assign_trait:ident, $assign_method:ident) => {
Expand Down Expand Up @@ -761,3 +796,5 @@ impl_op!(BitXor, bitxor, BitXorAssign, bitxor_assign);
impl_op!(Add, add, AddAssign, add_assign);
impl_op!(Sub, sub, SubAssign, sub_assign);
impl_op!(Mul, mul, MulAssign, mul_assign);
impl_op!(Div, div, DivAssign, div_assign);
impl_op!(Rem, rem, RemAssign, rem_assign);
Loading

0 comments on commit 13d4c9a

Please sign in to comment.