Skip to content

Commit

Permalink
Implement core::ops (rust-lang#10)
Browse files Browse the repository at this point in the history
* Add vector-vector arithmetic ops
* Add operators and integer conversions for masks
* Add unary traits
* Implement Index and IndexMut
* Implement by-ref ops for masks
* Document intrinsics
* Implement format traits for masks
* Add floating point ops tests
* Add integer tests
* Add mask tests
  • Loading branch information
calebzulawski authored Oct 2, 2020
1 parent fa6bb81 commit 43dabd1
Show file tree
Hide file tree
Showing 33 changed files with 2,233 additions and 1 deletion.
39 changes: 39 additions & 0 deletions crates/core_simd/src/intrinsics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//! This module contains the LLVM intrinsics bindings that provide the functionality for this
//! crate.
//!
//! The LLVM assembly language is documented here: https://llvm.org/docs/LangRef.html
/// These intrinsics aren't linked directly from LLVM and are mostly undocumented, however they are
/// simply lowered to the matching LLVM instructions by the compiler. The associated instruction
/// is documented alongside each intrinsic.
extern "platform-intrinsic" {
/// add/fadd
pub(crate) fn simd_add<T>(x: T, y: T) -> T;

/// sub/fsub
pub(crate) fn simd_sub<T>(x: T, y: T) -> T;

/// mul/fmul
pub(crate) fn simd_mul<T>(x: T, y: T) -> T;

/// udiv/sdiv/fdiv
pub(crate) fn simd_div<T>(x: T, y: T) -> T;

/// urem/srem/frem
pub(crate) fn simd_rem<T>(x: T, y: T) -> T;

/// shl
pub(crate) fn simd_shl<T>(x: T, y: T) -> T;

/// lshr/ashr
pub(crate) fn simd_shr<T>(x: T, y: T) -> T;

/// and
pub(crate) fn simd_and<T>(x: T, y: T) -> T;

/// or
pub(crate) fn simd_or<T>(x: T, y: T) -> T;

/// xor
pub(crate) fn simd_xor<T>(x: T, y: T) -> T;
}
4 changes: 3 additions & 1 deletion crates/core_simd/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#![no_std]
#![feature(repr_simd)]
#![feature(repr_simd, platform_intrinsics)]
#![warn(missing_docs)]
//! Portable SIMD module.
#[macro_use]
mod macros;

mod fmt;
mod intrinsics;
mod ops;

mod masks;
pub use masks::*;
Expand Down
51 changes: 51 additions & 0 deletions crates/core_simd/src/masks.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
/// The error type returned when converting an integer to a mask fails.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromMaskError(());

impl core::fmt::Display for TryFromMaskError {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "mask must have all bits set or unset")
}
}

macro_rules! define_mask {
{ $(#[$attr:meta])* struct $name:ident($type:ty); } => {
$(#[$attr])*
Expand Down Expand Up @@ -34,11 +44,52 @@ macro_rules! define_mask {
}
}

impl core::convert::TryFrom<$type> for $name {
type Error = TryFromMaskError;
fn try_from(value: $type) -> Result<Self, Self::Error> {
if value == 0 || !value == 0 {
Ok(Self(value))
} else {
Err(TryFromMaskError(()))
}
}
}

impl core::convert::From<$name> for $type {
fn from(value: $name) -> Self {
value.0
}
}

impl core::fmt::Debug for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
self.test().fmt(f)
}
}

impl core::fmt::Binary for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
<$type as core::fmt::Binary>::fmt(&self.0, f)
}
}

impl core::fmt::Octal for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
<$type as core::fmt::Octal>::fmt(&self.0, f)
}
}

impl core::fmt::LowerHex for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
<$type as core::fmt::LowerHex>::fmt(&self.0, f)
}
}

impl core::fmt::UpperHex for $name {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
<$type as core::fmt::UpperHex>::fmt(&self.0, f)
}
}
}
}

Expand Down
Loading

0 comments on commit 43dabd1

Please sign in to comment.