Skip to content

i128 intrinsics #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 4, 2017
Merged
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",
]);

for src in sources.files.iter() {
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