Skip to content

Add traits for integer operations #26

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 1 commit into from
Aug 11, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 59 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,76 @@
#[cfg(test)]
extern crate core;

use core::mem;

#[cfg(target_arch = "arm")]
pub mod arm;

#[cfg(test)]
mod test;

const CHAR_BITS: usize = 8;
/// Trait for some basic operations on integers
trait Int {
fn bits() -> usize;
}

// TODO: Once i128/u128 support lands, we'll want to add impls for those as well
impl Int for u32 {
fn bits() -> usize { 32 }
}
impl Int for i32 {
fn bits() -> usize { 32 }
}
impl Int for u64 {
fn bits() -> usize { 64 }
}
impl Int for i64 {
fn bits() -> usize { 64 }
}

/// Trait to convert an integer to/from smaller parts
trait LargeInt {
type LowHalf;
type HighHalf;

fn low(self) -> Self::LowHalf;
fn high(self) -> Self::HighHalf;
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;

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)
}
}
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)
}
}

macro_rules! absv_i2 {
($intrinsic:ident : $ty:ty) => {
#[no_mangle]
pub extern "C" fn $intrinsic(x: $ty) -> $ty {
let n = mem::size_of::<$ty>() * CHAR_BITS;
let n = <$ty>::bits();
if x == 1 << (n - 1) {
panic!();
}
Expand Down