소스 검색

u128 sdiv intrinsics

est31 8 년 전
부모
커밋
9013dbef02
4개의 변경된 파일31개의 추가작업 그리고 8개의 파일을 삭제
  1. 2 2
      README.md
  2. 0 2
      build.rs
  3. 22 4
      src/int/sdiv.rs
  4. 7 0
      src/lib.rs

+ 2 - 2
README.md

@@ -195,7 +195,7 @@ These builtins are needed to support 128-bit integers, which are in the process
 
 - [x] ashlti3.c
 - [x] ashrti3.c
-- [ ] divti3.c
+- [x] divti3.c
 - [ ] fixdfti.c
 - [ ] fixsfti.c
 - [ ] fixunsdfti.c
@@ -205,7 +205,7 @@ These builtins are needed to support 128-bit integers, which are in the process
 - [ ] floatuntidf.c
 - [ ] floatuntisf.c
 - [x] lshrti3.c
-- [ ] modti3.c
+- [x] modti3.c
 - [x] muloti4.c
 - [x] multi3.c
 - [x] udivmodti4.c

+ 0 - 2
build.rs

@@ -182,7 +182,6 @@ fn main() {
                              "cmpti2.c",
                              "ctzti2.c",
                              "divtf3.c",
-                             "divti3.c",
                              "ffsti2.c",
                              "fixdfti.c",
                              "fixsfti.c",
@@ -196,7 +195,6 @@ fn main() {
                              "floatuntidf.c",
                              "floatuntisf.c",
                              "floatuntixf.c",
-                             "modti3.c",
                              "multf3.c",
                              "mulvti3.c",
                              "negti2.c",

+ 22 - 4
src/int/sdiv.rs

@@ -2,9 +2,12 @@ use int::Int;
 
 macro_rules! div {
     ($intrinsic:ident: $ty:ty, $uty:ty) => {
+        div!($intrinsic: $ty, $uty, $ty, |i| {i});
+    };
+    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
         /// Returns `a / b`
         #[cfg_attr(not(test), no_mangle)]
-        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
+        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
             let s_a = a >> (<$ty>::bits() - 1);
             let s_b = b >> (<$ty>::bits() - 1);
             let a = (a ^ s_a) - s_a;
@@ -12,23 +15,26 @@ macro_rules! div {
             let s = s_a ^ s_b;
 
             let r = udiv!(a as $uty, b as $uty);
-            (r as $ty ^ s) - s
+            ($conv)((r as $ty ^ s) - s)
         }
     }
 }
 
 macro_rules! mod_ {
     ($intrinsic:ident: $ty:ty, $uty:ty) => {
+        mod_!($intrinsic: $ty, $uty, $ty, |i| {i});
+    };
+    ($intrinsic:ident: $ty:ty, $uty:ty, $tyret:ty, $conv:expr) => {
         /// Returns `a % b`
         #[cfg_attr(not(test), no_mangle)]
-        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $ty {
+        pub extern "C" fn $intrinsic(a: $ty, b: $ty) -> $tyret {
             let s = b >> (<$ty>::bits() - 1);
             let b = (b ^ s) - s;
             let s = a >> (<$ty>::bits() - 1);
             let a = (a ^ s) - s;
 
             let r = urem!(a as $uty, b as $uty);
-            (r as $ty ^ s) - s
+            ($conv)((r as $ty ^ s) - s)
         }
     }
 }
@@ -61,12 +67,24 @@ div!(__divsi3: i32, u32);
 #[cfg(not(all(feature = "c", target_arch = "x86")))]
 div!(__divdi3: i64, u64);
 
+#[cfg(not(all(windows, target_pointer_width="64")))]
+div!(__divti3: i128, u128);
+
+#[cfg(all(windows, target_pointer_width="64"))]
+div!(__divti3: i128, u128, ::U64x2, ::sconv);
+
 #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
 mod_!(__modsi3: i32, u32);
 
 #[cfg(not(all(feature = "c", target_arch = "x86")))]
 mod_!(__moddi3: i64, u64);
 
+#[cfg(not(all(windows, target_pointer_width="64")))]
+mod_!(__modti3: i128, u128);
+
+#[cfg(all(windows, target_pointer_width="64"))]
+mod_!(__modti3: i128, u128, ::U64x2, ::sconv);
+
 #[cfg(not(all(feature = "c", target_arch = "arm", not(target_os = "ios"))))]
 divmod!(__divmodsi4, __divsi3: i32);
 

+ 7 - 0
src/lib.rs

@@ -100,6 +100,13 @@ fn conv(i: u128) -> U64x2 {
     U64x2(i.low(), i.high())
 }
 
+#[cfg(all(windows, target_pointer_width="64"))]
+fn sconv(i: i128) -> U64x2 {
+    use int::LargeInt;
+    let j = i as u128;
+    U64x2(j.low(), j.high())
+}
+
 #[cfg(test)]
 #[cfg_attr(target_arch = "arm", macro_use)]
 extern crate quickcheck;