Skip to content

Commit 43dabd1

Browse files
Implement core::ops (rust-lang#10)
* 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
1 parent fa6bb81 commit 43dabd1

33 files changed

+2233
-1
lines changed

crates/core_simd/src/intrinsics.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//! This module contains the LLVM intrinsics bindings that provide the functionality for this
2+
//! crate.
3+
//!
4+
//! The LLVM assembly language is documented here: https://llvm.org/docs/LangRef.html
5+
6+
/// These intrinsics aren't linked directly from LLVM and are mostly undocumented, however they are
7+
/// simply lowered to the matching LLVM instructions by the compiler. The associated instruction
8+
/// is documented alongside each intrinsic.
9+
extern "platform-intrinsic" {
10+
/// add/fadd
11+
pub(crate) fn simd_add<T>(x: T, y: T) -> T;
12+
13+
/// sub/fsub
14+
pub(crate) fn simd_sub<T>(x: T, y: T) -> T;
15+
16+
/// mul/fmul
17+
pub(crate) fn simd_mul<T>(x: T, y: T) -> T;
18+
19+
/// udiv/sdiv/fdiv
20+
pub(crate) fn simd_div<T>(x: T, y: T) -> T;
21+
22+
/// urem/srem/frem
23+
pub(crate) fn simd_rem<T>(x: T, y: T) -> T;
24+
25+
/// shl
26+
pub(crate) fn simd_shl<T>(x: T, y: T) -> T;
27+
28+
/// lshr/ashr
29+
pub(crate) fn simd_shr<T>(x: T, y: T) -> T;
30+
31+
/// and
32+
pub(crate) fn simd_and<T>(x: T, y: T) -> T;
33+
34+
/// or
35+
pub(crate) fn simd_or<T>(x: T, y: T) -> T;
36+
37+
/// xor
38+
pub(crate) fn simd_xor<T>(x: T, y: T) -> T;
39+
}

crates/core_simd/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#![no_std]
2-
#![feature(repr_simd)]
2+
#![feature(repr_simd, platform_intrinsics)]
33
#![warn(missing_docs)]
44
//! Portable SIMD module.
55
66
#[macro_use]
77
mod macros;
88

99
mod fmt;
10+
mod intrinsics;
11+
mod ops;
1012

1113
mod masks;
1214
pub use masks::*;

crates/core_simd/src/masks.rs

+51
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
/// The error type returned when converting an integer to a mask fails.
2+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
3+
pub struct TryFromMaskError(());
4+
5+
impl core::fmt::Display for TryFromMaskError {
6+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
7+
write!(f, "mask must have all bits set or unset")
8+
}
9+
}
10+
111
macro_rules! define_mask {
212
{ $(#[$attr:meta])* struct $name:ident($type:ty); } => {
313
$(#[$attr])*
@@ -34,11 +44,52 @@ macro_rules! define_mask {
3444
}
3545
}
3646

47+
impl core::convert::TryFrom<$type> for $name {
48+
type Error = TryFromMaskError;
49+
fn try_from(value: $type) -> Result<Self, Self::Error> {
50+
if value == 0 || !value == 0 {
51+
Ok(Self(value))
52+
} else {
53+
Err(TryFromMaskError(()))
54+
}
55+
}
56+
}
57+
58+
impl core::convert::From<$name> for $type {
59+
fn from(value: $name) -> Self {
60+
value.0
61+
}
62+
}
63+
3764
impl core::fmt::Debug for $name {
3865
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
3966
self.test().fmt(f)
4067
}
4168
}
69+
70+
impl core::fmt::Binary for $name {
71+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
72+
<$type as core::fmt::Binary>::fmt(&self.0, f)
73+
}
74+
}
75+
76+
impl core::fmt::Octal for $name {
77+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
78+
<$type as core::fmt::Octal>::fmt(&self.0, f)
79+
}
80+
}
81+
82+
impl core::fmt::LowerHex for $name {
83+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
84+
<$type as core::fmt::LowerHex>::fmt(&self.0, f)
85+
}
86+
}
87+
88+
impl core::fmt::UpperHex for $name {
89+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
90+
<$type as core::fmt::UpperHex>::fmt(&self.0, f)
91+
}
92+
}
4293
}
4394
}
4495

0 commit comments

Comments
 (0)