-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
SIMD groundwork part 1 #27169
SIMD groundwork part 1 #27169
Changes from all commits
c8b6d5b
c66554c
e364f0e
4f44258
1bfbde6
9af385b
78eead6
f1d3b02
ecb3df5
8d8b489
cb1eb9d
5889127
717da95
dbcd9f0
48f3507
bef1828
4fe138c
9b26895
e61f539
907bbac
9d78efb
f6275b7
627784b
67d56db
29b79aa
2a408ef
d598bdd
2115468
1f5739f
8b68f58
3e50067
926b835
84de8ca
4b24249
62ba85b
d792925
891c914
502f9ac
b067e44
02e9734
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,25 +10,12 @@ | |
|
||
//! SIMD vectors. | ||
//! | ||
//! These types can be used for accessing basic SIMD operations. Each of them | ||
//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div, | ||
//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently | ||
//! These types can be used for accessing basic SIMD operations. Currently | ||
//! comparison operators are not implemented. To use SSE3+, you must enable | ||
//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more | ||
//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are | ||
//! provided beyond this module. | ||
//! | ||
//! ```rust | ||
//! #![feature(core_simd)] | ||
//! | ||
//! fn main() { | ||
//! use std::simd::f32x4; | ||
//! let a = f32x4(40.0, 41.0, 42.0, 43.0); | ||
//! let b = f32x4(1.0, 1.1, 3.4, 9.8); | ||
//! println!("{:?}", a + b); | ||
//! } | ||
//! ``` | ||
//! | ||
//! # Stability Note | ||
//! | ||
//! These are all experimental. The interface may change entirely, without | ||
|
@@ -37,64 +24,120 @@ | |
#![unstable(feature = "core_simd", | ||
reason = "needs an RFC to flesh out the design", | ||
issue = "27731")] | ||
#![deprecated(since = "1.3.0", | ||
reason = "use the external `simd` crate instead")] | ||
|
||
#![allow(non_camel_case_types)] | ||
#![allow(missing_docs)] | ||
#![allow(deprecated)] | ||
|
||
use ops::{Add, Sub, Mul, Div, Shl, Shr, BitAnd, BitOr, BitXor}; | ||
|
||
// FIXME(stage0): the contents of macro can be inlined. | ||
// ABIs are verified as valid as soon as they are parsed, i.e. before | ||
// `cfg` stripping. The `platform-intrinsic` ABI is new, so stage0 | ||
// doesn't know about it, but it still errors out when it hits it | ||
// (despite this being in a `cfg(not(stage0))` module). | ||
macro_rules! argh { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain in a comment why we need this macro? It seems like its contents could just be inlined. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ABIs are verified as valid as soon as they are parsed, i.e. before (This is also included as an in-source comment.) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh wow, this is a very neat trick, it should be part of our usual bootstrapping toolbox! |
||
() => { | ||
extern "platform-intrinsic" { | ||
fn simd_add<T>(x: T, y: T) -> T; | ||
fn simd_sub<T>(x: T, y: T) -> T; | ||
fn simd_mul<T>(x: T, y: T) -> T; | ||
fn simd_div<T>(x: T, y: T) -> T; | ||
fn simd_shl<T>(x: T, y: T) -> T; | ||
fn simd_shr<T>(x: T, y: T) -> T; | ||
fn simd_and<T>(x: T, y: T) -> T; | ||
fn simd_or<T>(x: T, y: T) -> T; | ||
fn simd_xor<T>(x: T, y: T) -> T; | ||
} | ||
} | ||
} | ||
argh!(); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i8x16(pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i16x8(pub i16, pub i16, pub i16, pub i16, | ||
pub i16, pub i16, pub i16, pub i16); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i32x4(pub i32, pub i32, pub i32, pub i32); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i64x2(pub i64, pub i64); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u8x16(pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u16x8(pub u16, pub u16, pub u16, pub u16, | ||
pub u16, pub u16, pub u16, pub u16); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u64x2(pub u64, pub u64); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32); | ||
|
||
#[simd] | ||
#[repr(simd)] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct f64x2(pub f64, pub f64); | ||
|
||
macro_rules! impl_traits { | ||
($($trayt: ident, $method: ident, $func: ident: $($ty: ty),*;)*) => { | ||
$($( | ||
impl $trayt<$ty> for $ty { | ||
type Output = Self; | ||
fn $method(self, other: Self) -> Self { | ||
unsafe { | ||
$func(self, other) | ||
} | ||
} | ||
} | ||
)*)* | ||
} | ||
} | ||
|
||
impl_traits! { | ||
Add, add, simd_add: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; | ||
Sub, sub, simd_sub: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; | ||
Mul, mul, simd_mul: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2, f32x4, f64x2; | ||
|
||
Div, div, simd_div: f32x4, f64x2; | ||
|
||
Shl, shl, simd_shl: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; | ||
Shr, shr, simd_shr: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; | ||
BitAnd, bitand, simd_and: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; | ||
BitOr, bitor, simd_or: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; | ||
BitXor, bitxor, simd_xor: u8x16, u16x8, u32x4, u64x2, i8x16, i16x8, i32x4, i64x2; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
//! SIMD vectors. | ||
//! | ||
//! These types can be used for accessing basic SIMD operations. Each of them | ||
//! implements the standard arithmetic operator traits (Add, Sub, Mul, Div, | ||
//! Rem, Shl, Shr) through compiler magic, rather than explicitly. Currently | ||
//! comparison operators are not implemented. To use SSE3+, you must enable | ||
//! the features, like `-C target-feature=sse3,sse4.1,sse4.2`, or a more | ||
//! specific `target-cpu`. No other SIMD intrinsics or high-level wrappers are | ||
//! provided beyond this module. | ||
//! | ||
//! ```rust | ||
//! # #![feature(core_simd)] | ||
//! fn main() { | ||
//! use std::simd::f32x4; | ||
//! let a = f32x4(40.0, 41.0, 42.0, 43.0); | ||
//! let b = f32x4(1.0, 1.1, 3.4, 9.8); | ||
//! println!("{:?}", a + b); | ||
//! } | ||
//! ``` | ||
//! | ||
//! # Stability Note | ||
//! | ||
//! These are all experimental. The interface may change entirely, without | ||
//! warning. | ||
|
||
#![unstable(feature = "core_simd", | ||
reason = "needs an RFC to flesh out the design")] | ||
|
||
#![allow(non_camel_case_types)] | ||
#![allow(missing_docs)] | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i8x16(pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8, | ||
pub i8, pub i8, pub i8, pub i8); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i16x8(pub i16, pub i16, pub i16, pub i16, | ||
pub i16, pub i16, pub i16, pub i16); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i32x4(pub i32, pub i32, pub i32, pub i32); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct i64x2(pub i64, pub i64); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u8x16(pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8, | ||
pub u8, pub u8, pub u8, pub u8); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u16x8(pub u16, pub u16, pub u16, pub u16, | ||
pub u16, pub u16, pub u16, pub u16); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct u64x2(pub u64, pub u64); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32); | ||
|
||
#[simd] | ||
#[derive(Copy, Clone, Debug)] | ||
#[repr(C)] | ||
pub struct f64x2(pub f64, pub f64); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can possible replace the double-mod with just
#[cfg_attr(stage0, path = "simd_old.rs")] pub mod simd;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cfg_attr
doesn't work withpath
, e.g.Fails to compile with:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, that's unfortunate.