Prechádzať zdrojové kódy

i128 mul intrinsics

est31 8 rokov pred
rodič
commit
3055aa21b6
4 zmenil súbory, kde vykonal 24 pridanie a 12 odobranie
  1. 2 2
      README.md
  2. 0 2
      build.rs
  3. 19 8
      src/int/mul.rs
  4. 3 0
      src/lib.rs

+ 2 - 2
README.md

@@ -206,8 +206,8 @@ These builtins are needed to support 128-bit integers, which are in the process
 - [ ] floatuntisf.c
 - [ ] lshrti3.c
 - [ ] modti3.c
-- [ ] muloti4.c
-- [ ] multi3.c
+- [x] muloti4.c
+- [x] multi3.c
 - [ ] udivmodti4.c
 - [ ] udivti3.c
 - [ ] umodti3.c

+ 0 - 2
build.rs

@@ -150,7 +150,6 @@ fn main() {
                          "int_util.c",
                          "muldc3.c",
                          "muldf3.c",
-                         "muloti4.c",
                          "mulsc3.c",
                          "mulsf3.c",
                          "mulvdi3.c",
@@ -202,7 +201,6 @@ fn main() {
                              "lshrti3.c",
                              "modti3.c",
                              "multf3.c",
-                             "multi3.c",
                              "mulvti3.c",
                              "negti2.c",
                              "negvti2.c",

+ 19 - 8
src/int/mul.rs

@@ -1,9 +1,8 @@
-#[cfg(not(all(feature = "c", target_arch = "x86")))]
 use int::LargeInt;
 use int::Int;
 
 macro_rules! mul {
-    ($intrinsic:ident: $ty:ty) => {
+    ($intrinsic:ident: $ty:ty, $tyh:ty) => {
         /// Returns `a * b`
         #[cfg_attr(not(test), no_mangle)]
         pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
@@ -14,14 +13,15 @@ macro_rules! mul {
             low &= lower_mask;
             t += (a.low() >> half_bits).wrapping_mul(b.low() & lower_mask);
             low += (t & lower_mask) << half_bits;
-            let mut high = t >> half_bits;
+            let mut high = (t >> half_bits) as $tyh;
             t = low >> half_bits;
             low &= lower_mask;
             t += (b.low() >> half_bits).wrapping_mul(a.low() & lower_mask);
             low += (t & lower_mask) << half_bits;
-            high += t >> half_bits;
-            high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits);
-            high = high.wrapping_add(a.high().wrapping_mul(b.low()).wrapping_add(a.low().wrapping_mul(b.high())));
+            high += (t >> half_bits) as $tyh;
+            high += (a.low() >> half_bits).wrapping_mul(b.low() >> half_bits) as $tyh;
+            high = high.wrapping_add(a.high().wrapping_mul(b.low() as $tyh))
+                       .wrapping_add((a.low() as $tyh).wrapping_mul(b.high()));
             <$ty>::from_parts(low, high)
         }
     }
@@ -29,9 +29,13 @@ macro_rules! mul {
 
 macro_rules! mulo {
     ($intrinsic:ident: $ty:ty) => {
+        // Default is "C" ABI
+        mulo!($intrinsic: $ty, "C");
+    };
+    ($intrinsic:ident: $ty:ty, $abi:tt) => {
         /// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
         #[cfg_attr(not(test), no_mangle)]
-        pub extern "C" fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
+        pub extern $abi fn $intrinsic(a: $ty, b: $ty, overflow: &mut i32) -> $ty {
             *overflow = 0;
             let result = a.wrapping_mul(b);
             if a == <$ty>::min_value() {
@@ -69,11 +73,18 @@ macro_rules! mulo {
 }
 
 #[cfg(not(all(feature = "c", target_arch = "x86")))]
-mul!(__muldi3: u64);
+mul!(__muldi3: u64, u32);
+
+mul!(__multi3: i128, i64);
 
 mulo!(__mulosi4: i32);
 mulo!(__mulodi4: i64);
 
+#[cfg(all(windows, target_pointer_width="64"))]
+mulo!(__muloti4: i128, "unadjusted");
+#[cfg(not(all(windows, target_pointer_width="64")))]
+mulo!(__muloti4: i128);
+
 #[cfg(test)]
 mod tests {
     use qc::{I32, I64, U64};

+ 3 - 0
src/lib.rs

@@ -14,6 +14,9 @@
 #![feature(naked_functions)]
 #![feature(staged_api)]
 #![feature(i128_type)]
+#![feature(repr_simd)]
+#![feature(abi_unadjusted)]
+#![allow(unused_features)]
 #![no_builtins]
 #![unstable(feature = "compiler_builtins_lib",
             reason = "Compiler builtins. Will never become stable.",