about summary refs log tree commit diff
path: root/library/stdarch/crates/simd-test-macro/src
diff options
context:
space:
mode:
authorgnzlbg <gonzalobg88@gmail.com>2019-01-22 19:20:18 +0100
committergnzlbg <gnzlbg@users.noreply.github.com>2019-01-22 19:51:05 +0100
commit8ebe7deadcd99504e29da24feb14f15b23043fc2 (patch)
tree9302ca6dd1f596311d4a12b787197c6eebdf3125 /library/stdarch/crates/simd-test-macro/src
parent5f7006df5a945332e4f2a20a88b3ded8ce5c44fa (diff)
downloadrust-8ebe7deadcd99504e29da24feb14f15b23043fc2.tar.gz
rust-8ebe7deadcd99504e29da24feb14f15b23043fc2.zip
Automatically insert emms after running each MMX test
After using MMX intrinsics the FPU must be
cleared by using _mm_empty() before interfacing
with any x87 code.

This commit makes the simd_test macro automatically do that
when one of the features enabled is "mmx".
Diffstat (limited to 'library/stdarch/crates/simd-test-macro/src')
-rw-r--r--library/stdarch/crates/simd-test-macro/src/lib.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/library/stdarch/crates/simd-test-macro/src/lib.rs b/library/stdarch/crates/simd-test-macro/src/lib.rs
index e965634edec..4b0abc6e23c 100644
--- a/library/stdarch/crates/simd-test-macro/src/lib.rs
+++ b/library/stdarch/crates/simd-test-macro/src/lib.rs
@@ -44,6 +44,8 @@ pub fn simd_test(
         .map(String::from)
         .collect();
 
+    let mmx = target_features.iter().any(|s| s.starts_with("mmx"));
+
     let enable_feature = string(enable_feature);
     let item = TokenStream::from(item);
     let name = find_name(item.clone());
@@ -102,6 +104,15 @@ pub fn simd_test(
         TokenStream::new()
     };
 
+    let emms = if mmx {
+        // note: if the test requires MMX we need to clear the FPU
+        // registers once the test finishes before interfacing with
+        // other x87 code:
+        quote! { unsafe { super::_mm_empty() }; }
+    } else {
+        TokenStream::new()
+    };
+
     let ret: TokenStream = quote_spanned! {
         proc_macro2::Span::call_site() =>
         #[allow(non_snake_case)]
@@ -109,7 +120,9 @@ pub fn simd_test(
         #maybe_ignore
         fn #name() {
             if #force_test | (#cfg_target_features) {
-                return unsafe { #name() };
+                let v = unsafe { #name() };
+                #emms
+                return v;
             } else {
                 ::stdsimd_test::assert_skip_test_ok(stringify!(#name));
             }