Skip to content
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