Skip to content

Commit 5f74dbd

Browse files
gnzlbgalexcrichton
authored andcommitted
[mips/mips64: msa] add add_a_b intrinsic (#365)
* [mips64/msa] add add_a_b intrinsic * add make/file to mips64el's Dockerfile * add run-time detection support for mips64 * add mips64 build bot * generate docs for mips64 * fix linux test * cleanup rt-detection * support mips64/mips64el in stdsimd-test * support asserting instructions with in their name * better error msgs for the auxv_crate test * debug auxv on mips64 * override run-time detection on mips msa tests * remove unused #[macro_use] * try another MIPS cpu * detect default TARGET in simd-test-macro * use mips64r2-generic * disable unused function in mips tests * move msa to mips * remove mips from ci * split into mips and mips64 modules * add rt-detection for 32-bit mips * fmt * remove merge error * add norun build bots for mips * add -p to avoid changing the cwd * fixup * refactor run-time detection module
1 parent bcb720e commit 5f74dbd

31 files changed

+1413
-966
lines changed

.travis.yml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ matrix:
1212
- env: TARGET=arm-unknown-linux-gnueabihf
1313
- env: TARGET=armv7-unknown-linux-gnueabihf
1414
- env: TARGET=aarch64-unknown-linux-gnu
15+
- env: TARGET=mips-unknown-linux-gnu NORUN=1
16+
- env: TARGET=mipsel-unknown-linux-gnu NORUN=1
17+
- env: TARGET=mips64-unknown-linux-gnuabi64 NORUN=1
18+
- env: TARGET=mips64el-unknown-linux-gnuabi64 NORUN=1
1519
- env: TARGET=powerpc-unknown-linux-gnu
1620
- env: TARGET=powerpc64-unknown-linux-gnu
1721
- env: TARGET=powerpc64le-unknown-linux-gnu
@@ -21,11 +25,6 @@ matrix:
2125
- os: osx
2226
env: TARGET=x86_64-apple-darwin NO_ADD=1
2327
script: ci/run.sh
24-
- env: DOCUMENTATION
25-
install: true
26-
script: ci/dox.sh
27-
- script: cargo test --manifest-path crates/stdsimd-verify/Cargo.toml
28-
install: true
2928
- env: TARGET=wasm32-unknown-unknown
3029
before_script:
3130
- git clone --recursive https://github.com/WebAssembly/wabt
@@ -39,6 +38,11 @@ matrix:
3938
- cat wasm.wat
4039
- grep current_memory wasm.wat
4140
- grep grow_memory wasm.wat
41+
- env: DOCUMENTATION
42+
install: true
43+
script: ci/dox.sh
44+
- script: cargo test --manifest-path crates/stdsimd-verify/Cargo.toml
45+
install: true
4246
- env: RUSTFMT=On TARGET=x86_64-unknown-linux-gnu NO_ADD=1
4347
before_script:
4448
- rustup component add rustfmt-preview
@@ -60,7 +64,13 @@ install:
6064

6165
script:
6266
- cargo generate-lockfile
63-
- ci/run-docker.sh $TARGET $FEATURES
67+
- |
68+
if [ "$NORUN" == "1" ]; then
69+
cargo build --target=$TARGET -p coresimd -p stdsimd --manifest-path crates/stdsimd/Cargo.toml
70+
cargo build --release --target=$TARGET -p coresimd -p stdsimd --manifest-path crates/stdsimd/Cargo.toml
71+
else
72+
ci/run-docker.sh $TARGET $FEATURES
73+
fi
6474
6575
notifications:
6676
email:

ci/dox.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ dox arm armv7-unknown-linux-gnueabihf
4242
dox aarch64 aarch64-unknown-linux-gnu
4343
dox powerpc powerpc-unknown-linux-gnu
4444
dox powerpc64 powerpc64-unknown-linux-gnu
45+
dox mips mips-unknown-linux-gnu
46+
dox mips64 mips64-unknown-linux-gnuabi64
4547

4648
# If we're on travis, not a PR, and on the right branch, publish!
4749
if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_BRANCH" = "master" ]; then

coresimd/mips/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
//! MIPS
2+
3+
mod msa;
4+
pub use self::msa::*;

coresimd/mips/msa.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//! MIPS SIMD Architecture intrinsics
2+
//!
3+
//! The reference is [MIPS Architecture for Programmers Volume IV-j: The
4+
//! MIPS32 SIMD Architecture Module Revision 1.12][msa_ref].
5+
//!
6+
//! [msa_ref]: http://cdn2.imgtec.com/documentation/MD00866-2B-MSA32-AFP-01.12.pdf
7+
8+
#[cfg(test)]
9+
use stdsimd_test::assert_instr;
10+
use coresimd::simd::*;
11+
12+
#[allow(improper_ctypes)]
13+
extern "C" {
14+
#[link_name = "llvm.mips.add.a.b"]
15+
fn msa_add_a_b(a: i8x16, b: i8x16) -> i8x16;
16+
}
17+
18+
/// Vector Add Absolute Values.
19+
///
20+
/// Adds the absolute values of the elements in `a` and `b` into the result vector.
21+
#[inline]
22+
#[target_feature(enable = "msa")]
23+
#[cfg_attr(test, assert_instr(add_a.b))]
24+
pub unsafe fn __msa_add_a_b(a: i8x16, b: i8x16) -> i8x16 {
25+
msa_add_a_b(a, b)
26+
}
27+
28+
#[cfg(test)]
29+
mod tests {
30+
use simd::*;
31+
use stdsimd_test::simd_test;
32+
use coresimd::mips64::msa;
33+
34+
#[simd_test = "msa"]
35+
unsafe fn __msa_add_a_b() {
36+
#[cfg_attr(rustfmt, rustfmt_skip)]
37+
let a = i8x16::new(
38+
1, 2, 3, 4,
39+
1, 2, 3, 4,
40+
1, 2, 3, 4,
41+
1, 2, 3, 4,
42+
);
43+
#[cfg_attr(rustfmt, rustfmt_skip)]
44+
let b = i8x16::new(
45+
-4, -3, -2, -1,
46+
-4, -3, -2, -1,
47+
-4, -3, -2, -1,
48+
-4, -3, -2, -1,
49+
);
50+
let r = i8x16::splat(5);
51+
52+
assert_eq!(r, msa::__msa_add_a_b(a, b));
53+
}
54+
}

coresimd/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,15 @@ pub mod simd {
2929
/// * [`x86_64`]
3030
/// * [`arm`]
3131
/// * [`aarch64`]
32+
/// * [`mips`]
33+
/// * [`mips64`]
3234
///
3335
/// [`x86`]: https://rust-lang-nursery.github.io/stdsimd/x86/stdsimd/arch/index.html
3436
/// [`x86_64`]: https://rust-lang-nursery.github.io/stdsimd/x86_64/stdsimd/arch/index.html
3537
/// [`arm`]: https://rust-lang-nursery.github.io/stdsimd/arm/stdsimd/arch/index.html
3638
/// [`aarch64`]: https://rust-lang-nursery.github.io/stdsimd/aarch64/stdsimd/arch/index.html
39+
/// [`mips`]: https://rust-lang-nursery.github.io/stdsimd/mips/stdsimd/arch/index.html
40+
/// [`mips64`]: https://rust-lang-nursery.github.io/stdsimd/mips64/stdsimd/arch/index.html
3741
#[unstable(feature = "stdsimd", issue = "0")]
3842
pub mod arch {
3943
/// Platform-specific intrinsics for the `x86` platform.
@@ -81,6 +85,24 @@ pub mod arch {
8185
pub mod wasm32 {
8286
pub use coresimd::wasm32::*;
8387
}
88+
89+
/// Platform-specific intrinsics for the `mips` platform.
90+
///
91+
/// See the [module documentation](../index.html) for more details.
92+
#[cfg(any(target_arch = "mips", dox))]
93+
#[doc(cfg(target_arch = "mips"))]
94+
pub mod mips {
95+
pub use coresimd::mips::*;
96+
}
97+
98+
/// Platform-specific intrinsics for the `mips64` platform.
99+
///
100+
/// See the [module documentation](../index.html) for more details.
101+
#[cfg(any(target_arch = "mips64", dox))]
102+
#[doc(cfg(target_arch = "mips64"))]
103+
pub mod mips64 {
104+
pub use coresimd::mips::*;
105+
}
84106
}
85107

86108
mod simd_llvm;
@@ -97,4 +119,7 @@ mod aarch64;
97119
#[cfg(target_arch = "wasm32")]
98120
mod wasm32;
99121

122+
#[cfg(any(target_arch = "mips", target_arch = "mips64", dox))]
123+
mod mips;
124+
100125
mod nvptx;

crates/assert-instr-macro/src/lib.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,15 @@ pub fn assert_instr(
3939
(quote! { #[ignore] }).into()
4040
};
4141
let name = &func.ident;
42+
use quote::ToTokens;
43+
let instr_str = instr
44+
.clone()
45+
.into_tokens()
46+
.to_string()
47+
.replace('.', "_")
48+
.replace(|c: char| c.is_whitespace(), "");
4249
let assert_name = syn::Ident::from(
43-
&format!("assert_{}_{}", name.as_ref(), instr.as_ref())[..],
50+
&format!("assert_{}_{}", name.as_ref(), instr_str)[..],
4451
);
4552
let shim_name = syn::Ident::from(format!("{}_shim", name.as_ref()));
4653
let mut inputs = Vec::new();
@@ -72,7 +79,7 @@ pub fn assert_instr(
7279
attr.path
7380
.segments
7481
.first()
75-
.unwrap()
82+
.expect("attr.path.segments.first() failed")
7683
.value()
7784
.ident
7885
.as_ref()
@@ -109,7 +116,8 @@ pub fn assert_instr(
109116
}
110117
}.into();
111118
// why? necessary now to get tests to work?
112-
let tts: TokenStream = tts.to_string().parse().unwrap();
119+
let tts: TokenStream =
120+
tts.to_string().parse().expect("cannot parse tokenstream");
113121

114122
let tts: TokenStream = quote! {
115123
#item
@@ -119,13 +127,13 @@ pub fn assert_instr(
119127
}
120128

121129
struct Invoc {
122-
instr: syn::Ident,
130+
instr: syn::Expr,
123131
args: Vec<(syn::Ident, syn::Expr)>,
124132
}
125133

126134
impl syn::synom::Synom for Invoc {
127135
named!(parse -> Self, map!(parens!(do_parse!(
128-
instr: syn!(syn::Ident) >>
136+
instr: syn!(syn::Expr) >>
129137
args: many0!(do_parse!(
130138
syn!(syn::token::Comma) >>
131139
name: syn!(syn::Ident) >>

crates/simd-test-macro/src/lib.rs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,48 @@ pub fn simd_test(
5353
let item = TokenStream::from(item);
5454
let name = find_name(item.clone());
5555

56-
let name: TokenStream = name.as_str().parse().unwrap();
56+
let name: TokenStream = name.as_str()
57+
.parse()
58+
.expect(&format!("failed to parse name: {}", name.clone().as_str()));
5759

58-
let target = env::var("TARGET").unwrap();
59-
let macro_test = match target.split('-').next().unwrap() {
60+
let default_target = if cfg!(target_os = "windows") {
61+
Some("x86_64-pc-windows-msvc")
62+
} else if cfg!(target_os = "linux") {
63+
Some("x86_64-unknown-linux-gnu")
64+
} else if cfg!(target_os = "macos") {
65+
Some("x86_64-apple-darwin")
66+
} else {
67+
None
68+
};
69+
70+
let target = env::var("TARGET").unwrap_or_else(|_| {
71+
default_target.expect("TARGET environment variable not set and no default target known for the current target.").to_string()
72+
});
73+
let mut force_test = false;
74+
let macro_test = match target
75+
.split('-')
76+
.next()
77+
.expect(&format!("target triple contained no \"-\": {}", target))
78+
{
6079
"i686" | "x86_64" | "i586" => "is_x86_feature_detected",
6180
"arm" => "is_arm_feature_detected",
6281
"aarch64" => "is_aarch64_feature_detected",
6382
"powerpc64" => "is_powerpc64_feature_detected",
83+
"mips" | "mipsel" => {
84+
// FIXME:
85+
// On MIPS CI run-time feature detection always returns false due
86+
// to this qemu bug: https://bugs.launchpad.net/qemu/+bug/1754372
87+
//
88+
// This is a workaround to force the MIPS tests to always run on
89+
// CI.
90+
force_test = true;
91+
"is_mips_feature_detected"
92+
}
93+
"mips64" | "mips64el" => {
94+
// FIXME: see above
95+
force_test = true;
96+
"is_mips64_feature_detected"
97+
}
6498
t => panic!("unknown target: {}", t),
6599
};
66100
let macro_test = proc_macro2::Term::intern(macro_test);
@@ -82,7 +116,7 @@ pub fn simd_test(
82116
#[allow(non_snake_case)]
83117
#[test]
84118
fn #name() {
85-
if #cfg_target_features {
119+
if #force_test | (#cfg_target_features) {
86120
return unsafe { #name() };
87121
} else {
88122
::stdsimd_test::assert_skip_test_ok(stringify!(#name));

crates/stdsimd/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ mod stdsimd;
2929

3030
pub use stdsimd::*;
3131

32+
#[allow(unused_imports)]
3233
use _std::prelude;
34+
#[allow(unused_imports)]
3335
use _std::fs;
36+
#[allow(unused_imports)]
3437
use _std::io;

0 commit comments

Comments
 (0)