diff --git a/build.rs b/build.rs index e2a63a6..d7f6c01 100644 --- a/build.rs +++ b/build.rs @@ -129,6 +129,12 @@ mod tests { Divsf3, Divdf3, + // int/add.rs + AddU128, + AddI128, + AddoU128, + AddoI128, + // int/mul.rs Muldi3, Mulodi4, @@ -154,6 +160,12 @@ mod tests { Lshrdi3, Lshrti3, + // int/sub.rs + SubU128, + SubI128, + SuboU128, + SuboI128, + // int/udiv.rs Udivdi3, Udivmoddi4, @@ -341,6 +353,242 @@ fn addsf3() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct AddU128 { + a: u128, + b: u128, + c: u128, + } + + impl TestCase for AddU128 { + fn name() -> &'static str { + "u128_add" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + let b = gen_u128(rng); + let c = a.wrapping_add(b); + + Some(AddU128 { a, b, c }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), {c}),", + a = self.a, + b = self.b, + c = self.c + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::add::rust_u128_add; + +static TEST_CASES: &[((u128, u128), u128)] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn u128_add() { + for &((a, b), c) in TEST_CASES { + let c_ = rust_u128_add(a, b); + assert_eq!(((a, b), c), ((a, b), c_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct AddI128 { + a: i128, + b: i128, + c: i128, + } + + impl TestCase for AddI128 { + fn name() -> &'static str { + "i128_add" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + let b = gen_i128(rng); + let c = a.wrapping_add(b); + + Some(AddI128 { a, b, c }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), {c}),", + a = self.a, + b = self.b, + c = self.c + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::add::rust_i128_add; + +static TEST_CASES: &[((i128, i128), i128)] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn i128_add() { + for &((a, b), c) in TEST_CASES { + let c_ = rust_i128_add(a, b); + assert_eq!(((a, b), c), ((a, b), c_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct AddoU128 { + a: u128, + b: u128, + c: u128, + d: bool, + } + + impl TestCase for AddoU128 { + fn name() -> &'static str { + "u128_addo" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + let b = gen_u128(rng); + let (c, d) = a.overflowing_add(b); + + Some(AddoU128 { a, b, c, d }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), ({c}, {d})),", + a = self.a, + b = self.b, + c = self.c, + d = self.d + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::add::rust_u128_addo; + +static TEST_CASES: &[((u128, u128), (u128, bool))] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn u128_addo() { + for &((a, b), (c, d)) in TEST_CASES { + let (c_, d_) = rust_u128_addo(a, b); + assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_))); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct AddoI128 { + a: i128, + b: i128, + c: i128, + d: bool, + } + + impl TestCase for AddoI128 { + fn name() -> &'static str { + "i128_addo" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + let b = gen_i128(rng); + let (c, d) = a.overflowing_add(b); + + Some(AddoI128 { a, b, c, d }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), ({c}, {d})),", + a = self.a, + b = self.b, + c = self.c, + d = self.d + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::add::rust_i128_addo; + +static TEST_CASES: &[((i128, i128), (i128, bool))] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn i128_addo() { + for &((a, b), (c, d)) in TEST_CASES { + let (c_, d_) = rust_i128_addo(a, b); + assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Ashldi3 { a: u64, @@ -3229,6 +3477,242 @@ fn subsf3() { } } + #[derive(Eq, Hash, PartialEq)] + pub struct SubU128 { + a: u128, + b: u128, + c: u128, + } + + impl TestCase for SubU128 { + fn name() -> &'static str { + "u128_sub" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + let b = gen_u128(rng); + let c = a.wrapping_sub(b); + + Some(SubU128 { a, b, c }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), {c}),", + a = self.a, + b = self.b, + c = self.c + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::sub::rust_u128_sub; + +static TEST_CASES: &[((u128, u128), u128)] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn u128_sub() { + for &((a, b), c) in TEST_CASES { + let c_ = rust_u128_sub(a, b); + assert_eq!(((a, b), c), ((a, b), c_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct SubI128 { + a: i128, + b: i128, + c: i128, + } + + impl TestCase for SubI128 { + fn name() -> &'static str { + "i128_sub" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + let b = gen_i128(rng); + let c = a.wrapping_sub(b); + + Some(SubI128 { a, b, c }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), {c}),", + a = self.a, + b = self.b, + c = self.c + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::sub::rust_i128_sub; + +static TEST_CASES: &[((i128, i128), i128)] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn i128_sub() { + for &((a, b), c) in TEST_CASES { + let c_ = rust_i128_sub(a, b); + assert_eq!(((a, b), c), ((a, b), c_)); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct SuboU128 { + a: u128, + b: u128, + c: u128, + d: bool, + } + + impl TestCase for SuboU128 { + fn name() -> &'static str { + "u128_subo" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_u128(rng); + let b = gen_u128(rng); + let (c, d) = a.overflowing_sub(b); + + Some(SuboU128 { a, b, c, d }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), ({c}, {d})),", + a = self.a, + b = self.b, + c = self.c, + d = self.d + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::sub::rust_u128_subo; + +static TEST_CASES: &[((u128, u128), (u128, bool))] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn u128_subo() { + for &((a, b), (c, d)) in TEST_CASES { + let (c_, d_) = rust_u128_subo(a, b); + assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_))); + } +} +" + } + } + + #[derive(Eq, Hash, PartialEq)] + pub struct SuboI128 { + a: i128, + b: i128, + c: i128, + d: bool, + } + + impl TestCase for SuboI128 { + fn name() -> &'static str { + "i128_subo" + } + + fn generate(rng: &mut R) -> Option + where + R: Rng, + Self: Sized, + { + let a = gen_i128(rng); + let b = gen_i128(rng); + let (c, d) = a.overflowing_sub(b); + + Some(SuboI128 { a, b, c, d }) + } + + fn to_string(&self, buffer: &mut String) { + writeln!( + buffer, + "(({a}, {b}), ({c}, {d})),", + a = self.a, + b = self.b, + c = self.c, + d = self.d + ) + .unwrap(); + } + + fn prologue() -> &'static str { + " +use compiler_builtins::int::sub::rust_i128_subo; + +static TEST_CASES: &[((i128, i128), (i128, bool))] = &[ +" + } + + fn epilogue() -> &'static str { + " +]; + +#[test] +fn i128_subo() { + for &((a, b), (c, d)) in TEST_CASES { + let (c_, d_) = rust_i128_subo(a, b); + assert_eq!(((a, b), (c, d)), ((a, b), (c_, d_))); + } +} +" + } + } + #[derive(Eq, Hash, PartialEq)] pub struct Mulsf3 { a: u32, // f32 diff --git a/src/int/add.rs b/src/int/add.rs index b0f7ab6..5c746c2 100644 --- a/src/int/add.rs +++ b/src/int/add.rs @@ -65,56 +65,3 @@ pub fn rust_u128_addo(a: u128, b: u128) -> (u128, bool) { let r = a.addo(b, &mut oflow); (r, oflow != 0) } - -#[test] -fn test_add() { - assert_eq!(rust_u128_add(1, 2), 3); - assert_eq!(rust_u128_add(!0, 3), 2); - assert_eq!(rust_u128_add(1 << 63, 1 << 63), 1 << 64); - assert_eq!(rust_u128_add( - 0x54009B79B43145A0_B781BF1FD491296E_u128, - 0x6019CEECA5354210_839AB51D155FF7F3_u128), - 0xB41A6A66596687B1_3B1C743CE9F12161_u128); - assert_eq!(rust_u128_add( - 0x3AE89C3AACEE47CD_8721275248B38DDB_u128, - 0xEFDD73C41D344744_B0842900C3352A63_u128), - 0x2AC60FFECA228F12_37A550530BE8B83E_u128); - - assert_eq!(rust_i128_add(1, 2), 3); - assert_eq!(rust_i128_add(-1, 3), 2); -} - -#[test] -fn test_addo() { - assert_eq!(rust_u128_addo(1, 2), (3, false)); - assert_eq!(rust_u128_addo(!0, 3), (2, true)); - assert_eq!(rust_u128_addo(1 << 63, 1 << 63), (1 << 64, false)); - assert_eq!(rust_u128_addo( - 0x54009B79B43145A0_B781BF1FD491296E_u128, - 0x6019CEECA5354210_839AB51D155FF7F3_u128), - (0xB41A6A66596687B1_3B1C743CE9F12161_u128, false)); - assert_eq!(rust_u128_addo( - 0x3AE89C3AACEE47CD_8721275248B38DDB_u128, - 0xEFDD73C41D344744_B0842900C3352A63_u128), - (0x2AC60FFECA228F12_37A550530BE8B83E_u128, true)); - - assert_eq!(rust_i128_addo(1, 2), (3, false)); - assert_eq!(rust_i128_addo(-1, 3), (2, false)); - assert_eq!(rust_i128_addo(1 << 63, 1 << 63), (1 << 64, false)); - assert_eq!(rust_i128_addo( - 0x54009B79B43145A0_B781BF1FD491296E_i128, - 0x6019CEECA5354210_839AB51D155FF7F3_i128), - (-0x4BE59599A699784E_C4E38BC3160EDE9F_i128, true)); - assert_eq!(rust_i128_addo( - 0x3AE89C3AACEE47CD_8721275248B38DDB_i128, - -0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128), - (0x2AC60FFECA228F12_37A550530BE8B83E_i128, false)); - assert_eq!(rust_i128_addo( - -0x54009B79B43145A0_B781BF1FD491296E_i128, - -0x6019CEECA5354210_839AB51D155FF7F3_i128), - (0x4BE59599A699784E_C4E38BC3160EDE9F_i128, true)); - assert_eq!(rust_i128_addo( - -0x3AE89C3AACEE47CD_8721275248B38DDB_i128, - 0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128), - (-0x2AC60FFECA228F12_37A550530BE8B83E_i128, false)); -} \ No newline at end of file diff --git a/src/int/sub.rs b/src/int/sub.rs index 0b0cbf2..abcb45a 100644 --- a/src/int/sub.rs +++ b/src/int/sub.rs @@ -50,56 +50,3 @@ pub fn rust_u128_subo(a: u128, b: u128) -> (u128, bool) { let r = a.subo(b, &mut oflow); (r, oflow != 0) } - -#[test] -fn test_sub() { - assert_eq!(rust_u128_sub(3, 2), 1); - assert_eq!(rust_u128_sub(2, 3), !0); - assert_eq!(rust_u128_sub(1 << 64, 1 << 63), 1 << 63); - assert_eq!(rust_u128_sub( - 0xB41A6A66596687B1_3B1C743CE9F12161_u128, - 0x6019CEECA5354210_839AB51D155FF7F3_u128), - 0x54009B79B43145A0_B781BF1FD491296E_u128); - assert_eq!(rust_u128_sub( - 0x2AC60FFECA228F12_37A550530BE8B83E_u128, - 0xEFDD73C41D344744_B0842900C3352A63_u128), - 0x3AE89C3AACEE47CD_8721275248B38DDB_u128); - - assert_eq!(rust_i128_sub(3, 2), 1); - assert_eq!(rust_i128_sub(2, 3), -1); -} - -#[test] -fn test_subo() { - assert_eq!(rust_u128_subo(3, 2), (1, false)); - assert_eq!(rust_u128_subo(2, 3), (!0, true)); - assert_eq!(rust_u128_subo(1 << 64, 1 << 63), (1 << 63, false)); - assert_eq!(rust_u128_subo( - 0xB41A6A66596687B1_3B1C743CE9F12161_u128, - 0x6019CEECA5354210_839AB51D155FF7F3_u128), - (0x54009B79B43145A0_B781BF1FD491296E_u128, false)); - assert_eq!(rust_u128_subo( - 0x2AC60FFECA228F12_37A550530BE8B83E_u128, - 0xEFDD73C41D344744_B0842900C3352A63_u128), - (0x3AE89C3AACEE47CD_8721275248B38DDB_u128, true)); - - assert_eq!(rust_i128_subo(3, 2), (1, false)); - assert_eq!(rust_i128_subo(2, 3), (-1, false)); - assert_eq!(rust_i128_subo(1 << 64, 1 << 63), (1 << 63, false)); - assert_eq!(rust_i128_subo( - -0x4BE59599A699784E_C4E38BC3160EDE9F_i128, - 0x6019CEECA5354210_839AB51D155FF7F3_i128), - (0x54009B79B43145A0_B781BF1FD491296E_i128, true)); - assert_eq!(rust_i128_subo( - 0x2AC60FFECA228F12_37A550530BE8B83E_i128, - -0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128), - (0x3AE89C3AACEE47CD_8721275248B38DDB_i128, false)); - assert_eq!(rust_i128_subo( - 0x4BE59599A699784E_C4E38BC3160EDE9F_i128, - -0x6019CEECA5354210_839AB51D155FF7F3_i128), - (-0x54009B79B43145A0_B781BF1FD491296E_i128, true)); - assert_eq!(rust_i128_subo( - -0x2AC60FFECA228F12_37A550530BE8B83E_i128, - 0x10228C3BE2CBB8BB_4F7BD6FF3CCAD59D_i128), - (-0x3AE89C3AACEE47CD_8721275248B38DDB_i128, false)); -} \ No newline at end of file diff --git a/tests/i128_add.rs b/tests/i128_add.rs new file mode 100644 index 0000000..13af050 --- /dev/null +++ b/tests/i128_add.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/i128_add.rs")); diff --git a/tests/i128_addo.rs b/tests/i128_addo.rs new file mode 100644 index 0000000..306ffac --- /dev/null +++ b/tests/i128_addo.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/i128_addo.rs")); diff --git a/tests/i128_sub.rs b/tests/i128_sub.rs new file mode 100644 index 0000000..933fe4f --- /dev/null +++ b/tests/i128_sub.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/i128_sub.rs")); diff --git a/tests/i128_subo.rs b/tests/i128_subo.rs new file mode 100644 index 0000000..0c2b67c --- /dev/null +++ b/tests/i128_subo.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/i128_subo.rs")); diff --git a/tests/u128_add.rs b/tests/u128_add.rs new file mode 100644 index 0000000..d4b8f2c --- /dev/null +++ b/tests/u128_add.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/u128_add.rs")); diff --git a/tests/u128_addo.rs b/tests/u128_addo.rs new file mode 100644 index 0000000..caff682 --- /dev/null +++ b/tests/u128_addo.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/u128_addo.rs")); diff --git a/tests/u128_sub.rs b/tests/u128_sub.rs new file mode 100644 index 0000000..024266b --- /dev/null +++ b/tests/u128_sub.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/u128_sub.rs")); diff --git a/tests/u128_subo.rs b/tests/u128_subo.rs new file mode 100644 index 0000000..b3fb4b8 --- /dev/null +++ b/tests/u128_subo.rs @@ -0,0 +1,8 @@ +#![feature(compiler_builtins_lib)] +#![feature(i128_type)] +#![cfg_attr(all(target_arch = "arm", + not(any(target_env = "gnu", target_env = "musl")), + target_os = "linux", + test), no_std)] + +include!(concat!(env!("OUT_DIR"), "/u128_subo.rs"));