Skip to content

Commit 011aafe

Browse files
committed
Add initial type implementations
1 parent 8ee9cba commit 011aafe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+533
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[workspace]
2+
3+
members = [
4+
"crates/core_simd",
5+
]

crates/core_simd/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[package]
2+
name = "core_simd"
3+
version = "0.1.0"
4+
authors = ["Caleb Zulawski <[email protected]>"]
5+
edition = "2018"

crates/core_simd/src/lib.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![feature(repr_simd)]
2+
3+
#[macro_use]
4+
mod macros;
5+
6+
macro_rules! import_types {
7+
{ $($mod:ident,)* } => {
8+
$(
9+
mod $mod;
10+
pub use $mod::*;
11+
)*
12+
}
13+
}
14+
15+
import_types! {
16+
type_u8x2, type_u8x4, type_u8x8, type_u8x16, type_u8x32, type_u8x64,
17+
type_i8x2, type_i8x4, type_i8x8, type_i8x16, type_i8x32, type_i8x64,
18+
type_u16x2, type_u16x4, type_u16x8, type_u16x16, type_u16x32,
19+
type_i16x2, type_i16x4, type_i16x8, type_i16x16, type_i16x32,
20+
type_u32x2, type_u32x4, type_u32x8, type_u32x16,
21+
type_i32x2, type_i32x4, type_i32x8, type_i32x16,
22+
type_u64x2, type_u64x4, type_u64x8,
23+
type_i64x2, type_i64x4, type_i64x8,
24+
type_u128x2, type_u128x4,
25+
type_i128x2, type_i128x4,
26+
}
27+
28+
import_types! {
29+
type_usizex2, type_usizex4, type_usizex8,
30+
type_isizex2, type_isizex4, type_isizex8,
31+
}
32+
33+
import_types! {
34+
type_f32x2, type_f32x4, type_f32x8, type_f32x16,
35+
type_f64x2, type_f64x4, type_f64x8,
36+
}

crates/core_simd/src/macros.rs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
macro_rules! from_aligned {
2+
{ unsafe $from:ty => $to:ty } => {
3+
impl core::convert::From<$from> for $to {
4+
#[inline]
5+
fn from(value: $from) -> $to {
6+
assert_eq!(core::mem::size_of::<$from>(), core::mem::size_of::<$to>());
7+
assert!(core::mem::align_of::<$from>() >= core::mem::align_of::<$to>());
8+
unsafe { core::mem::transmute(value) }
9+
}
10+
}
11+
};
12+
{ unsafe $a:ty |bidirectional| $b:ty } => {
13+
from_aligned!{ unsafe $a => $b }
14+
from_aligned!{ unsafe $b => $a }
15+
}
16+
}
17+
18+
macro_rules! from_unaligned {
19+
{ unsafe $from:ty => $to:ty } => {
20+
impl core::convert::From<$from> for $to {
21+
#[inline]
22+
fn from(value: $from) -> $to {
23+
assert_eq!(core::mem::size_of::<$from>(), core::mem::size_of::<$to>());
24+
unsafe { (&value as *const $from as *const $to).read_unaligned() }
25+
}
26+
}
27+
}
28+
}
29+
30+
macro_rules! define_type {
31+
{ struct $name:ident([$type:ty; $lanes:tt]); } => {
32+
define_type! { @impl $name [$type; $lanes] }
33+
34+
// array references
35+
impl AsRef<[$type; $lanes]> for $name {
36+
#[inline]
37+
fn as_ref(&self) -> &[$type; $lanes] {
38+
unsafe { &*(self as *const _ as *const _) }
39+
}
40+
}
41+
42+
impl AsMut<[$type; $lanes]> for $name {
43+
#[inline]
44+
fn as_mut(&mut self) -> &mut [$type; $lanes] {
45+
unsafe { &mut *(self as *mut _ as *mut _) }
46+
}
47+
}
48+
49+
// slice references
50+
impl AsRef<[$type]> for $name {
51+
#[inline]
52+
fn as_ref(&self) -> &[$type] {
53+
AsRef::<[$type; $lanes]>::as_ref(self)
54+
}
55+
}
56+
57+
impl AsMut<[$type]> for $name {
58+
#[inline]
59+
fn as_mut(&mut self) -> &mut [$type] {
60+
AsMut::<[$type; $lanes]>::as_mut(self)
61+
}
62+
}
63+
64+
// vector to array
65+
from_aligned! { unsafe $name => [$type; $lanes] }
66+
67+
// array to vector
68+
from_unaligned! { unsafe [$type; $lanes] => $name }
69+
70+
// splat
71+
impl From<$type> for $name {
72+
fn from(value: $type) -> Self {
73+
Self::splat(value)
74+
}
75+
}
76+
};
77+
{ @impl $name:ident [$type:ty; 1] } => {
78+
define_type! { @impl $name | $type | $type, | v0, }
79+
};
80+
{ @impl $name:ident [$type:ty; 2] } => {
81+
define_type! { @impl $name | $type | $type, $type, | v0, v1, }
82+
};
83+
{ @impl $name:ident [$type:ty; 4] } => {
84+
define_type! { @impl $name | $type |
85+
$type, $type, $type, $type, |
86+
v0, v1, v2, v3,
87+
}
88+
};
89+
{ @impl $name:ident [$type:ty; 8] } => {
90+
define_type! { @impl $name | $type |
91+
$type, $type, $type, $type, $type, $type, $type, $type, |
92+
v0, v1, v2, v3, v4, v5, v6, v7,
93+
}
94+
};
95+
{ @impl $name:ident [$type:ty; 16] } => {
96+
define_type! { @impl $name | $type |
97+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
98+
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
99+
}
100+
};
101+
{ @impl $name:ident [$type:ty; 32] } => {
102+
define_type! { @impl $name | $type |
103+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
104+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
105+
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
106+
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
107+
}
108+
};
109+
{ @impl $name:ident [$type:ty; 64] } => {
110+
define_type! { @impl $name | $type |
111+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
112+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
113+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type,
114+
$type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, $type, |
115+
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15,
116+
v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
117+
v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47,
118+
v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63,
119+
}
120+
};
121+
{ @impl $name:ident | $type:ty | $($itype:ty,)* | $($ivar:ident,)* } => {
122+
#[allow(non_camel_case_types)]
123+
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
124+
#[repr(simd)]
125+
pub struct $name($($itype),*);
126+
127+
impl $name {
128+
#[inline]
129+
pub fn splat(value: $type) -> Self {
130+
Self($(value as $itype),*)
131+
}
132+
133+
#[allow(clippy::too_many_arguments)]
134+
#[inline]
135+
pub fn new($($ivar: $itype),*) -> Self {
136+
Self($($ivar),*)
137+
}
138+
}
139+
}
140+
}

crates/core_simd/src/type_f32x16.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
define_type! { struct f32x16([f32; 16]); }
2+
3+
/*
4+
#[cfg(target_arch = "x86")]
5+
from_aligned! { unsafe f32x16 |bidirectional| core::arch::x86::__m512 }
6+
7+
#[cfg(target_arch = "x86_64")]
8+
from_aligned! { unsafe f32x16 |bidirectional| core::arch::x86_64::__m512 }
9+
*/

crates/core_simd/src/type_f32x2.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
define_type! { struct f32x2([f32; 2]); }

crates/core_simd/src/type_f32x4.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define_type! { struct f32x4([f32; 4]); }
2+
3+
#[cfg(target_arch = "x86")]
4+
from_aligned! { unsafe f32x4 |bidirectional| core::arch::x86::__m128 }
5+
6+
#[cfg(target_arch = "x86_64")]
7+
from_aligned! { unsafe f32x4 |bidirectional| core::arch::x86_64::__m128 }

crates/core_simd/src/type_f32x8.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define_type! { struct f32x8([f32; 8]); }
2+
3+
#[cfg(target_arch = "x86")]
4+
from_aligned! { unsafe f32x8 |bidirectional| core::arch::x86::__m256 }
5+
6+
#[cfg(target_arch = "x86_64")]
7+
from_aligned! { unsafe f32x8 |bidirectional| core::arch::x86_64::__m256 }

crates/core_simd/src/type_f64x2.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define_type! { struct f64x2([f64; 2]); }
2+
3+
#[cfg(target_arch = "x86")]
4+
from_aligned! { unsafe f64x2 |bidirectional| core::arch::x86::__m128d }
5+
6+
#[cfg(target_arch = "x86_64")]
7+
from_aligned! { unsafe f64x2 |bidirectional| core::arch::x86_64::__m128d }

0 commit comments

Comments
 (0)