Add traits for integer operations

master
Amanieu d'Antras 2016-08-11 05:28:15 +01:00
parent 1c9c2b4452
commit 8a94b69d85
1 changed files with 59 additions and 4 deletions

View File

@ -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!();
}