Skip to content

Commit

Permalink
Auto merge of #133 - est31:i128, r=japaric
Browse files Browse the repository at this point in the history
i128 intrinsics

Adds i128 intrinsics.

Note that this PR doesn't do float intrinsics, due to the missing presence of macros, those are however still required in order for rustc to switch to this crate.
  • Loading branch information
bors committed Feb 4, 2017
2 parents 0d0f22a + 37d3490 commit 9debde0
Show file tree
Hide file tree
Showing 12 changed files with 547 additions and 213 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ features = ["c"]

These builtins are needed to support 128-bit integers, which are in the process of being added to Rust.

- [ ] ashlti3.c
- [ ] ashrti3.c
- [ ] divti3.c
- [x] ashlti3.c
- [x] ashrti3.c
- [x] divti3.c
- [ ] fixdfti.c
- [ ] fixsfti.c
- [ ] fixunsdfti.c
Expand All @@ -204,13 +204,13 @@ These builtins are needed to support 128-bit integers, which are in the process
- [ ] floattisf.c
- [ ] floatuntidf.c
- [ ] floatuntisf.c
- [ ] lshrti3.c
- [ ] modti3.c
- [ ] muloti4.c
- [ ] multi3.c
- [ ] udivmodti4.c
- [ ] udivti3.c
- [ ] umodti3.c
- [x] lshrti3.c
- [x] modti3.c
- [x] muloti4.c
- [x] multi3.c
- [x] udivmodti4.c
- [x] udivti3.c
- [x] umodti3.c

## Unimplemented functions

Expand Down
12 changes: 1 addition & 11 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ fn main() {
"int_util.c",
"muldc3.c",
"muldf3.c",
"muloti4.c",
"mulsc3.c",
"mulsf3.c",
"mulvdi3.c",
Expand Down Expand Up @@ -179,13 +178,10 @@ fn main() {
sources.extend(&["absvti2.c",
"addtf3.c",
"addvti3.c",
"ashlti3.c",
"ashrti3.c",
"clzti2.c",
"cmpti2.c",
"ctzti2.c",
"divtf3.c",
"divti3.c",
"ffsti2.c",
"fixdfti.c",
"fixsfti.c",
Expand All @@ -199,10 +195,7 @@ fn main() {
"floatuntidf.c",
"floatuntisf.c",
"floatuntixf.c",
"lshrti3.c",
"modti3.c",
"multf3.c",
"multi3.c",
"mulvti3.c",
"negti2.c",
"negvti2.c",
Expand All @@ -212,10 +205,7 @@ fn main() {
"subtf3.c",
"subvti3.c",
"trampoline_setup.c",
"ucmpti2.c",
"udivmodti4.c",
"udivti3.c",
"umodti3.c"]);
"ucmpti2.c"]);
}

if target_vendor == "apple" {
Expand Down
11 changes: 11 additions & 0 deletions compiler-rt/compiler-rt-cdylib/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ fn main() {
"addsf3.c",
"powidf2.c",
"powisf2.c",
// 128 bit integers
"lshrti3.c",
"modti3.c",
"muloti4.c",
"multi3.c",
"udivmodti4.c",
"udivti3.c",
"umodti3.c",
"ashlti3.c",
"ashrti3.c",
"divti3.c",
]);

let builtins_dir = Path::new("compiler-rt/lib/builtins");
Expand Down
30 changes: 30 additions & 0 deletions compiler-rt/compiler-rt-cdylib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,36 @@ declare!(___adddf3, __adddf3);
declare!(___powisf2, __powisf2);
declare!(___powidf2, __powidf2);

#[cfg(all(not(windows),
not(target_arch = "mips64"),
not(target_arch = "mips64el"),
target_pointer_width="64"))]
pub mod int_128 {
extern {
fn __lshrti3();
fn __modti3();
fn __muloti4();
fn __multi3();
fn __udivmodti4();
fn __udivti3();
fn __umodti3();
fn __ashlti3();
fn __ashrti3();
fn __divti3();
}

declare!(___lshrti3, __lshrti3);
declare!(___modti3, __modti3);
declare!(___muloti4, __muloti4);
declare!(___multi3, __multi3);
declare!(___udivmodti4, __udivmodti4);
declare!(___udivti3, __udivti3);
declare!(___umodti3, __umodti3);
declare!(___ashlti3, __ashlti3);
declare!(___ashrti3, __ashrti3);
declare!(___divti3, __divti3);
}

#[lang = "eh_personality"]
fn eh_personality() {}
#[lang = "panic_fmt"]
Expand Down
46 changes: 46 additions & 0 deletions src/bin/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#![feature(lang_items)]
#![feature(libc)]
#![feature(start)]
#![feature(i128_type)]
#![no_std]

#[cfg(not(thumb))]
Expand Down Expand Up @@ -300,6 +301,42 @@ mod intrinsics {
pub fn umoddi3(a: u64, b: u64) -> u64 {
a % b
}

pub fn muloti4(a: u128, b: u128) -> Option<u128> {
a.checked_mul(b)
}

pub fn multi3(a: u128, b: u128) -> u128 {
a.wrapping_mul(b)
}

pub fn ashlti3(a: u128, b: usize) -> u128 {
a >> b
}

pub fn ashrti3(a: u128, b: usize) -> u128 {
a << b
}

pub fn lshrti3(a: i128, b: usize) -> i128 {
a >> b
}

pub fn udivti3(a: u128, b: u128) -> u128 {
a / b
}

pub fn umodti3(a: u128, b: u128) -> u128 {
a % b
}

pub fn divti3(a: i128, b: i128) -> i128 {
a / b
}

pub fn modti3(a: i128, b: i128) -> i128 {
a % b
}
}

#[cfg(feature = "c")]
Expand Down Expand Up @@ -356,6 +393,15 @@ fn run() {
bb(powidf2(bb(2.), bb(3)));
bb(powisf2(bb(2.), bb(3)));
bb(umoddi3(bb(2), bb(3)));
bb(muloti4(bb(2), bb(2)));
bb(multi3(bb(2), bb(2)));
bb(ashlti3(bb(2), bb(2)));
bb(ashrti3(bb(2), bb(2)));
bb(lshrti3(bb(2), bb(2)));
bb(udivti3(bb(2), bb(2)));
bb(umodti3(bb(2), bb(2)));
bb(divti3(bb(2), bb(2)));
bb(modti3(bb(2), bb(2)));
}

#[cfg(all(feature = "c", not(thumb)))]
Expand Down
94 changes: 50 additions & 44 deletions src/int/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
macro_rules! hty {
($ty:ty) => {
<$ty as LargeInt>::HighHalf
}
}

macro_rules! os_ty {
($ty:ty) => {
<$ty as Int>::OtherSign
}
}

pub mod mul;
pub mod sdiv;
Expand All @@ -6,32 +17,33 @@ pub mod udiv;

/// Trait for some basic operations on integers
pub trait Int {
/// Type with the same width but other signedness
type OtherSign;
/// Returns the bitwidth of the int type
fn bits() -> u32;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl Int for u32 {
fn bits() -> u32 {
32
}
}
impl Int for i32 {
fn bits() -> u32 {
32
}
}
impl Int for u64 {
fn bits() -> u32 {
64
}
}
impl Int for i64 {
fn bits() -> u32 {
64
macro_rules! int_impl {
($ity:ty, $sty:ty, $bits:expr) => {
impl Int for $ity {
type OtherSign = $sty;
fn bits() -> u32 {
$bits
}
}
impl Int for $sty {
type OtherSign = $ity;
fn bits() -> u32 {
$bits
}
}
}
}

int_impl!(i32, u32, 32);
int_impl!(i64, u64, 64);
int_impl!(i128, u128, 128);

/// Trait to convert an integer to/from smaller parts
pub trait LargeInt {
type LowHalf;
Expand All @@ -42,32 +54,26 @@ pub trait LargeInt {
fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl LargeInt for u64 {
type LowHalf = u32;
type HighHalf = u32;
macro_rules! large_int {
($ty:ty, $tylow:ty, $tyhigh:ty, $halfbits:expr) => {
impl LargeInt for $ty {
type LowHalf = $tylow;
type HighHalf = $tyhigh;

fn low(self) -> u32 {
self as u32
}
fn high(self) -> u32 {
(self >> 32) as u32
}
fn from_parts(low: u32, high: u32) -> u64 {
low as u64 | ((high as u64) << 32)
fn low(self) -> $tylow {
self as $tylow
}
fn high(self) -> $tyhigh {
(self >> $halfbits) as $tyhigh
}
fn from_parts(low: $tylow, high: $tyhigh) -> $ty {
low as $ty | ((high as $ty) << $halfbits)
}
}
}
}
impl LargeInt for i64 {
type LowHalf = u32;
type HighHalf = i32;

fn low(self) -> u32 {
self as u32
}
fn high(self) -> i32 {
(self >> 32) as i32
}
fn from_parts(low: u32, high: i32) -> i64 {
low as i64 | ((high as i64) << 32)
}
}
large_int!(u64, u32, u32, 32);
large_int!(i64, u32, i32, 32);
large_int!(u128, u64, u64, 64);
large_int!(i128, u64, i64, 64);
Loading

0 comments on commit 9debde0

Please sign in to comment.