Skip to content

Commit

Permalink
Big update
Browse files Browse the repository at this point in the history
  • Loading branch information
tgross35 committed Apr 14, 2024
1 parent 4a69a34 commit db3fb45
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 24 deletions.
47 changes: 24 additions & 23 deletions src/int/big.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,26 @@ const WORD_FULL_MASK: u64 = 0xffffffffffffffff;
// Stored little endian
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct u256([u64; 4]);
pub struct u256(pub [u64; 4]);

impl u256 {
/// Reinterpret as a signed integer
fn as_signed(self) -> i256 {
pub fn signed(self) -> i256 {
i256(self.0)
}
}

impl u256 {
impl i256 {
/// Reinterpret as an unsigned integer
fn as_unsigned(self) -> u256 {
pub fn unsigned(self) -> u256 {
u256(self.0)
}
}

// Stored little endian
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
pub struct i256([u64; 4]);
pub struct i256(pub [u64; 4]);

impl MinInt for u256 {
type OtherSign = i256;
Expand Down Expand Up @@ -194,7 +194,6 @@ macro_rules! impl_common {
impl_common!(i256);
impl_common!(u256);


macro_rules! word {
(1, $val:expr) => {
(($val >> (32 * 3)) & Self::from(WORD_LO_MASK)) as u64
Expand Down Expand Up @@ -280,34 +279,36 @@ impl HInt for i128 {
type D = i256;

fn widen(self) -> Self::D {
let w0 = self & i128::from(u64::MAX);
let w1 = (self >> u64::BITS) & i128::from(u64::MAX);
i256([w0 as u64, w1 as u64, u64::MAX, u64::MAX])
let mut ret = self.unsigned().zero_widen().signed();
if self.is_negative() {
ret.0[2] = u64::MAX;
ret.0[3] = u64::MAX;
}
ret
}

fn zero_widen(self) -> Self::D {
self.unsigned().zero_widen().as_signed()
self.unsigned().zero_widen().signed()
}

fn zero_widen_mul(self, rhs: Self) -> Self::D {
self.unsigned().zero_widen_mul(rhs.unsigned()).as_signed()
self.unsigned().zero_widen_mul(rhs.unsigned()).signed()
}

fn widen_mul(self, rhs: Self) -> Self::D {
let sign0 = self & (0b1 << 127);
let sign1 = rhs & (0b1 << 127);
let signed_res = sign0 ^ sign1;
let mut res = self.zero_widen_mul(rhs);
if self.is_negative() ^ rhs.is_negative() {
for word in res.0.iter_mut().rev() {
let zeroes = word.leading_zeros();
let leading = u64::MAX << (64 - zeroes);
*word |= leading;
if zeroes != 64 {
break
}
}
}

// if signed_res > 0 {
// for word in res.0.iter_mut().rev() {
// for shift in (0..=63).rev() {
// if
// todo!()
// }
// }
// }
todo!()
res
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/int/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub mod sdiv;
pub mod shift;
pub mod udiv;

pub use self::leading_zeros::__clzsi2;
pub use leading_zeros::__clzsi2;
pub use big::{i256, u256};

public_test_dep! {
/// Minimal integer implementations needed on all integer types, including wide integers.
Expand Down
23 changes: 23 additions & 0 deletions testcrate/tests/big.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use compiler_builtins::int::{i256, u256, HInt};

#[test]
fn widen_u128() {
assert_eq!(u128::MAX.widen(), u256([u64::MAX, u64::MAX, 0, 0]));
assert_eq!(
0xaaaaaaaaaaaaaaaaffffffffffffffff_u128.widen(),
u256([u64::MAX, 0xaaaaaaaaaaaaaaaa, 0, 0])
);
}

#[test]
fn widen_i128() {
assert_eq!(
(-1i128).widen(),
i256([u64::MAX, u64::MAX, u64::MAX, u64::MAX])
);
assert_eq!(
(0xaaaaaaaaaaaaaaaaffffffffffffffff_u128 as i128).widen(),
i256([u64::MAX, 0xaaaaaaaaaaaaaaaa, u64::MAX, u64::MAX])
);
assert_eq!((-1i128).zero_widen().unsigned(), (u128::MAX).widen());
}

0 comments on commit db3fb45

Please sign in to comment.