From 5a8887b0c0eb4ddb760f8f32109a66979f41b7a4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 21 Sep 2017 08:42:52 -0700 Subject: [PATCH] Add CI for more platforms This commit adds CI for a few more targets: * i686-unknown-linux-gnu * arm-unknown-linux-gnueabihf * armv7-unknown-linux-gnueabihf * aarch64-unknown-linux-gnu The CI here is structured around using a Docker container to set up a test environment and then QEMU is used to actually execute code from these platforms. QEMU's emulation actually makes it so we can continue to just use `cargo test`, as processes can be spawned from QEMU like `objdump` and files can be read (for libbacktrace). Ends up being a relatively seamless experience! Note that a number of intrinsics were disabled on i686 because they were failing tests, and otherwise a few ARM touch-ups were made to get tests passing. --- library/stdarch/.travis.yml | 19 +++-- library/stdarch/assert-instr/src/lib.rs | 12 ++- .../aarch64-unknown-linux-gnu/Dockerfile | 13 +++ .../arm-unknown-linux-gnueabihf/Dockerfile | 13 +++ .../armv7-unknown-linux-gnueabihf/Dockerfile | 13 +++ .../docker/i686-unknown-linux-gnu/Dockerfile | 7 ++ .../x86_64-unknown-linux-gnu/Dockerfile | 7 ++ library/stdarch/ci/run-docker.sh | 32 ++++++++ library/stdarch/ci/run.sh | 6 ++ library/stdarch/examples/play.rs | 81 ++++++++++--------- library/stdarch/examples/types.rs | 42 ++++++---- library/stdarch/examples/wat.rs | 42 ++++++---- library/stdarch/src/arm/v6.rs | 8 +- library/stdarch/src/arm/v7.rs | 4 + library/stdarch/src/arm/v8.rs | 7 +- library/stdarch/src/x86/bmi.rs | 5 ++ library/stdarch/src/x86/bmi2.rs | 7 +- library/stdarch/src/x86/tbm.rs | 9 +++ 18 files changed, 241 insertions(+), 86 deletions(-) create mode 100644 library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile create mode 100644 library/stdarch/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile create mode 100644 library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile create mode 100644 library/stdarch/ci/docker/i686-unknown-linux-gnu/Dockerfile create mode 100644 library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile create mode 100755 library/stdarch/ci/run-docker.sh create mode 100755 library/stdarch/ci/run.sh diff --git a/library/stdarch/.travis.yml b/library/stdarch/.travis.yml index 12638698cb44..f9876f63461f 100644 --- a/library/stdarch/.travis.yml +++ b/library/stdarch/.travis.yml @@ -1,15 +1,24 @@ language: rust sudo: false +rust: nightly matrix: include: - - rust: nightly - - rust: nightly - os: osx + - env: TARGET=i686-unknown-linux-gnu + - env: TARGET=x86_64-unknown-linux-gnu NO_ADD=1 + - env: TARGET=arm-unknown-linux-gnueabihf + - env: TARGET=armv7-unknown-linux-gnueabihf + - env: TARGET=aarch64-unknown-linux-gnu + - os: osx + env: TARGET=x86_64-apple-darwin NO_ADD=1 + script: ci/run.sh + +install: + - if [ "$NO_ADD" = "" ]; then rustup target add $TARGET; fi script: - - cargo test - - cargo test --release + - cargo generate-lockfile + - ci/run-docker.sh $TARGET notifications: email: diff --git a/library/stdarch/assert-instr/src/lib.rs b/library/stdarch/assert-instr/src/lib.rs index ada7b8bc3fa0..092f25e6a5aa 100644 --- a/library/stdarch/assert-instr/src/lib.rs +++ b/library/stdarch/assert-instr/src/lib.rs @@ -58,7 +58,8 @@ fn disassemble_myself() -> HashMap> { parse_otool(&str::from_utf8(&output.stdout).expect("stdout not utf8")) } else { - let output = Command::new("objdump") + let objdump = env::var("OBJDUMP").unwrap_or("objdump".to_string()); + let output = Command::new(objdump) .arg("--disassemble") .arg(&me) .output() @@ -72,6 +73,13 @@ fn disassemble_myself() -> HashMap> { fn parse_objdump(output: &str) -> HashMap> { let mut lines = output.lines(); + let expected_len = if cfg!(target_arch = "arm") { + 8 + } else if cfg!(target_arch = "aarch64") { + 8 + } else { + 2 + }; for line in output.lines().take(100) { println!("{}", line); @@ -97,7 +105,7 @@ fn parse_objdump(output: &str) -> HashMap> { let parts = instruction.split_whitespace() .skip(1) .skip_while(|s| { - s.len() == 2 && usize::from_str_radix(s, 16).is_ok() + s.len() == expected_len && usize::from_str_radix(s, 16).is_ok() }) .map(|s| s.to_string()) .collect::>(); diff --git a/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile new file mode 100644 index 000000000000..4e3bff0ac0a1 --- /dev/null +++ b/library/stdarch/ci/docker/aarch64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:17.10 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + ca-certificates \ + libc6-dev \ + gcc-aarch64-linux-gnu \ + libc6-dev-arm64-cross \ + qemu-user \ + make \ + file +ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ + CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER="qemu-aarch64 -L /usr/aarch64-linux-gnu" \ + OBJDUMP=aarch64-linux-gnu-objdump diff --git a/library/stdarch/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile b/library/stdarch/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile new file mode 100644 index 000000000000..c7bd61f0a796 --- /dev/null +++ b/library/stdarch/ci/docker/arm-unknown-linux-gnueabihf/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:17.10 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + ca-certificates \ + libc6-dev \ + gcc-arm-linux-gnueabihf \ + libc6-dev-armhf-cross \ + qemu-user \ + make \ + file +ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ + CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_RUNNER="qemu-arm -L /usr/arm-linux-gnueabihf" \ + OBJDUMP=arm-linux-gnueabihf-objdump diff --git a/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile b/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile new file mode 100644 index 000000000000..e01b87afdf56 --- /dev/null +++ b/library/stdarch/ci/docker/armv7-unknown-linux-gnueabihf/Dockerfile @@ -0,0 +1,13 @@ +FROM ubuntu:17.10 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + ca-certificates \ + libc6-dev \ + gcc-arm-linux-gnueabihf \ + libc6-dev-armhf-cross \ + qemu-user \ + make \ + file +ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ + CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_RUNNER="qemu-arm -L /usr/arm-linux-gnueabihf" \ + OBJDUMP=arm-linux-gnueabihf-objdump diff --git a/library/stdarch/ci/docker/i686-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/i686-unknown-linux-gnu/Dockerfile new file mode 100644 index 000000000000..2bea700920d1 --- /dev/null +++ b/library/stdarch/ci/docker/i686-unknown-linux-gnu/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:17.04 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc-multilib \ + libc6-dev \ + file \ + make \ + ca-certificates diff --git a/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile new file mode 100644 index 000000000000..5390c32516b0 --- /dev/null +++ b/library/stdarch/ci/docker/x86_64-unknown-linux-gnu/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:17.04 +RUN apt-get update && apt-get install -y --no-install-recommends \ + gcc \ + libc6-dev \ + file \ + make \ + ca-certificates diff --git a/library/stdarch/ci/run-docker.sh b/library/stdarch/ci/run-docker.sh new file mode 100755 index 000000000000..e5a19af544e2 --- /dev/null +++ b/library/stdarch/ci/run-docker.sh @@ -0,0 +1,32 @@ +# Small script to run tests for a target (or all targets) inside all the +# respective docker images. + +set -ex + +run() { + echo $1 + docker build -t stdsimd ci/docker/$1 + mkdir -p target + docker run \ + --user `id -u`:`id -g` \ + --rm \ + --init \ + --volume $HOME/.cargo:/cargo \ + --env CARGO_HOME=/cargo \ + --volume `rustc --print sysroot`:/rust:ro \ + --env TARGET=$1 \ + --volume `pwd`:/checkout:ro \ + --volume `pwd`/target:/checkout/target \ + --workdir /checkout \ + stdsimd \ + bash \ + -c 'PATH=$PATH:/rust/bin exec ci/run.sh $1' +} + +if [ -z "$1" ]; then + for d in `ls ci/docker/`; do + run $d + done +else + run $1 +fi diff --git a/library/stdarch/ci/run.sh b/library/stdarch/ci/run.sh new file mode 100755 index 000000000000..5995bcbc6ac9 --- /dev/null +++ b/library/stdarch/ci/run.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +set -ex + +cargo test --target $TARGET +cargo test --release --target $TARGET diff --git a/library/stdarch/examples/play.rs b/library/stdarch/examples/play.rs index 9bcdde0de9df..69b692fe12ea 100644 --- a/library/stdarch/examples/play.rs +++ b/library/stdarch/examples/play.rs @@ -1,48 +1,57 @@ #![feature(target_feature)] -extern crate stdsimd; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod example { -use std::env; -use stdsimd::simd as s; -use stdsimd::vendor; + extern crate stdsimd; -#[inline(never)] -#[target_feature = "+sse4.2"] -fn index(needle: &str, haystack: &str) -> usize { - assert!(needle.len() <= 16 && haystack.len() <= 16); + use std::env; + use self::stdsimd::simd as s; + use self::stdsimd::vendor; - let (needle_len, hay_len) = (needle.len(), haystack.len()); + #[inline(never)] + #[target_feature = "+sse4.2"] + fn index(needle: &str, haystack: &str) -> usize { + assert!(needle.len() <= 16 && haystack.len() <= 16); - let mut needle = needle.to_string().into_bytes(); - needle.resize(16, 0); - let vneedle = vendor::__m128i::from(s::u8x16::load(&needle, 0)); + let (needle_len, hay_len) = (needle.len(), haystack.len()); - let mut haystack = haystack.to_string().into_bytes(); - haystack.resize(16, 0); - let vhaystack = vendor::__m128i::from(s::u8x16::load(&haystack, 0)); + let mut needle = needle.to_string().into_bytes(); + needle.resize(16, 0); + let vneedle = vendor::__m128i::from(s::u8x16::load(&needle, 0)); - vendor::_mm_cmpestri( - vneedle, needle_len as i32, vhaystack, hay_len as i32, - vendor::_SIDD_CMP_EQUAL_ORDERED) as usize + let mut haystack = haystack.to_string().into_bytes(); + haystack.resize(16, 0); + let vhaystack = vendor::__m128i::from(s::u8x16::load(&haystack, 0)); + + vendor::_mm_cmpestri( + vneedle, needle_len as i32, vhaystack, hay_len as i32, + vendor::_SIDD_CMP_EQUAL_ORDERED) as usize + } + + pub fn main() { + // let x0: f64 = env::args().nth(1).unwrap().parse().unwrap(); + // let x1: f64 = env::args().nth(2).unwrap().parse().unwrap(); + // let x2: f64 = env::args().nth(3).unwrap().parse().unwrap(); + // let x3: f64 = env::args().nth(4).unwrap().parse().unwrap(); + // let y0: i32 = env::args().nth(5).unwrap().parse().unwrap(); + // let y1: i32 = env::args().nth(6).unwrap().parse().unwrap(); + // let y2: i32 = env::args().nth(7).unwrap().parse().unwrap(); + // let y3: i32 = env::args().nth(8).unwrap().parse().unwrap(); + + // let a = s::f64x2::new(x0, x1); + // let b = s::f64x2::new(x2, x3); + // let r = s::_mm_cmplt_sd(a, b); + // let r = foobar(a, b); + + + let needle = env::args().nth(1).unwrap(); + let haystack = env::args().nth(2).unwrap(); + println!("{:?}", index(&needle, &haystack)); + } } fn main() { - // let x0: f64 = env::args().nth(1).unwrap().parse().unwrap(); - // let x1: f64 = env::args().nth(2).unwrap().parse().unwrap(); - // let x2: f64 = env::args().nth(3).unwrap().parse().unwrap(); - // let x3: f64 = env::args().nth(4).unwrap().parse().unwrap(); - // let y0: i32 = env::args().nth(5).unwrap().parse().unwrap(); - // let y1: i32 = env::args().nth(6).unwrap().parse().unwrap(); - // let y2: i32 = env::args().nth(7).unwrap().parse().unwrap(); - // let y3: i32 = env::args().nth(8).unwrap().parse().unwrap(); - - // let a = s::f64x2::new(x0, x1); - // let b = s::f64x2::new(x2, x3); - // let r = s::_mm_cmplt_sd(a, b); - // let r = foobar(a, b); - - - let needle = env::args().nth(1).unwrap(); - let haystack = env::args().nth(2).unwrap(); - println!("{:?}", index(&needle, &haystack)); + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + example::main(); } diff --git a/library/stdarch/examples/types.rs b/library/stdarch/examples/types.rs index 37355ae78df2..a719b2c333a7 100644 --- a/library/stdarch/examples/types.rs +++ b/library/stdarch/examples/types.rs @@ -1,25 +1,33 @@ #![feature(target_feature)] -extern crate stdsimd; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod example { + extern crate stdsimd; -use std::env; -use stdsimd::simd; + use std::env; + use self::stdsimd::simd; -#[inline(never)] -#[target_feature = "-sse2"] -fn myop( - (x0, x1, x2, x3): (u64, u64, u64, u64), - (y0, y1, y2, y3): (u64, u64, u64, u64), -) -> (u64, u64, u64, u64) { - let x = simd::u64x4::new(x0, x1, x2, x3); - let y = simd::u64x4::new(y0, y1, y2, y3); - let r = x * y; - (r.extract(0), r.extract(1), r.extract(2), r.extract(3)) + #[inline(never)] + #[target_feature = "-sse2"] + fn myop( + (x0, x1, x2, x3): (u64, u64, u64, u64), + (y0, y1, y2, y3): (u64, u64, u64, u64), + ) -> (u64, u64, u64, u64) { + let x = simd::u64x4::new(x0, x1, x2, x3); + let y = simd::u64x4::new(y0, y1, y2, y3); + let r = x * y; + (r.extract(0), r.extract(1), r.extract(2), r.extract(3)) + } + + pub fn main() { + let x = env::args().nth(1).unwrap().parse().unwrap(); + let y = env::args().nth(1).unwrap().parse().unwrap(); + let r = myop((x, x, x, x), (y, y, y, y)); + println!("{:?}", r); + } } fn main() { - let x = env::args().nth(1).unwrap().parse().unwrap(); - let y = env::args().nth(1).unwrap().parse().unwrap(); - let r = myop((x, x, x, x), (y, y, y, y)); - println!("{:?}", r); + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + example::main(); } diff --git a/library/stdarch/examples/wat.rs b/library/stdarch/examples/wat.rs index debfaa811fa4..a85b780641c4 100644 --- a/library/stdarch/examples/wat.rs +++ b/library/stdarch/examples/wat.rs @@ -1,25 +1,33 @@ #![feature(target_feature)] -extern crate stdsimd; +#[cfg(any(target_arch = "x86", target_arch = "x86_64"))] +mod example { + extern crate stdsimd; -use std::env; -use stdsimd::simd; + use std::env; + use self::stdsimd::simd; -#[inline(never)] -#[target_feature = "-sse2"] -fn myop( - (x0, x1, x2, x3): (u64, u64, u64, u64), - (y0, y1, y2, y3): (u64, u64, u64, u64), -) -> (u64, u64, u64, u64) { - let x = simd::u64x4::new(x0, x1, x2, x3); - let y = simd::u64x4::new(y0, y1, y2, y3); - let r = x * y; - (r.extract(0), r.extract(1), r.extract(2), r.extract(3)) + #[inline(never)] + #[target_feature = "-sse2"] + fn myop( + (x0, x1, x2, x3): (u64, u64, u64, u64), + (y0, y1, y2, y3): (u64, u64, u64, u64), + ) -> (u64, u64, u64, u64) { + let x = simd::u64x4::new(x0, x1, x2, x3); + let y = simd::u64x4::new(y0, y1, y2, y3); + let r = x * y; + (r.extract(0), r.extract(1), r.extract(2), r.extract(3)) + } + + pub fn main() { + let x = env::args().nth(1).unwrap().parse().unwrap(); + let y = env::args().nth(2).unwrap().parse().unwrap(); + let r = myop((x, x, x, x), (y, y, y, y)); + println!("{:?}", r); + } } fn main() { - let x = env::args().nth(1).unwrap().parse().unwrap(); - let y = env::args().nth(2).unwrap().parse().unwrap(); - let r = myop((x, x, x, x), (y, y, y, y)); - println!("{:?}", r); + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + example::main(); } diff --git a/library/stdarch/src/arm/v6.rs b/library/stdarch/src/arm/v6.rs index 95442b374f8c..233481c3be97 100644 --- a/library/stdarch/src/arm/v6.rs +++ b/library/stdarch/src/arm/v6.rs @@ -3,12 +3,8 @@ //! The reference is [ARMv6-M Architecture Reference //! Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0419c/index.html). -/// Reverse the order of the bytes. -#[inline(always)] -#[cfg_attr(test, assert_instr(rev))] -pub fn _rev_u8(x: u8) -> u8 { - x.swap_bytes() as u8 -} +#[cfg(test)] +use assert_instr::assert_instr; /// Reverse the order of the bytes. #[inline(always)] diff --git a/library/stdarch/src/arm/v7.rs b/library/stdarch/src/arm/v7.rs index 1052b8477a92..4112212aa363 100644 --- a/library/stdarch/src/arm/v7.rs +++ b/library/stdarch/src/arm/v7.rs @@ -5,6 +5,9 @@ pub use super::v6::*; +#[cfg(test)] +use assert_instr::assert_instr; + /// Count Leading Zeros. #[inline(always)] #[cfg_attr(test, assert_instr(clz))] @@ -35,6 +38,7 @@ extern "C" { /// Reverse the bit order. #[inline(always)] #[cfg_attr(test, assert_instr(rbit))] +#[cfg_attr(target_arch = "arm", target_feature = "+v7")] pub fn _rbit_u32(x: u32) -> u32 { unsafe { rbit_u32(x as i32) as u32 } } diff --git a/library/stdarch/src/arm/v8.rs b/library/stdarch/src/arm/v8.rs index e49ca4fe1f25..6438f2d316ff 100644 --- a/library/stdarch/src/arm/v8.rs +++ b/library/stdarch/src/arm/v8.rs @@ -4,6 +4,9 @@ pub use super::v7::*; +#[cfg(test)] +use assert_instr::assert_instr; + /// Reverse the order of the bytes. #[inline(always)] #[cfg_attr(test, assert_instr(rev))] @@ -37,7 +40,7 @@ pub fn _rbit_u64(x: u64) -> u64 { /// bits. #[inline(always)] // LLVM Bug (should be cls): https://bugs.llvm.org/show_bug.cgi?id=31802 -#[cfg_attr(test, assert_instr(clz))] +#[cfg_attr(test, assert_instr(clz))] pub fn _cls_u32(x: u32) -> u32 { u32::leading_zeros(!x) as u32 } @@ -48,7 +51,7 @@ pub fn _cls_u32(x: u32) -> u32 { /// bits. #[inline(always)] // LLVM Bug (should be cls): https://bugs.llvm.org/show_bug.cgi?id=31802 -#[cfg_attr(test, assert_instr(clz))] +#[cfg_attr(test, assert_instr(clz))] pub fn _cls_u64(x: u64) -> u64 { u64::leading_zeros(!x) as u64 } diff --git a/library/stdarch/src/x86/bmi.rs b/library/stdarch/src/x86/bmi.rs index ae5dbf223801..b22a0608bf09 100644 --- a/library/stdarch/src/x86/bmi.rs +++ b/library/stdarch/src/x86/bmi.rs @@ -32,6 +32,7 @@ pub fn _bextr_u32(a: u32, start: u32, len: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi"] #[cfg_attr(test, assert_instr(bextr))] +#[cfg(not(target_arch = "x86"))] pub fn _bextr_u64(a: u64, start: u64, len: u64) -> u64 { _bextr2_u64(a, (start & 0xffu64) | ((len & 0xffu64) << 8u64)) } @@ -56,6 +57,7 @@ pub fn _bextr2_u32(a: u32, control: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi"] #[cfg_attr(test, assert_instr(bextr))] +#[cfg(not(target_arch = "x86"))] pub fn _bextr2_u64(a: u64, control: u64) -> u64 { unsafe { x86_bmi_bextr_64(a, control) } } @@ -88,6 +90,7 @@ pub fn _blsi_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi"] #[cfg_attr(test, assert_instr(blsi))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blsi_u64(x: u64) -> u64 { x & x.wrapping_neg() } @@ -104,6 +107,7 @@ pub fn _blsmsk_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi"] #[cfg_attr(test, assert_instr(blsmsk))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blsmsk_u64(x: u64) -> u64 { x ^ (x.wrapping_sub(1u64)) } @@ -124,6 +128,7 @@ pub fn _blsr_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi"] #[cfg_attr(test, assert_instr(blsr))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blsr_u64(x: u64) -> u64 { x & (x.wrapping_sub(1)) } diff --git a/library/stdarch/src/x86/bmi2.rs b/library/stdarch/src/x86/bmi2.rs index 67f8740399e4..ed1c2e3b9353 100644 --- a/library/stdarch/src/x86/bmi2.rs +++ b/library/stdarch/src/x86/bmi2.rs @@ -16,7 +16,8 @@ use assert_instr::assert_instr; /// the low half and the high half of the result. #[inline(always)] // LLVM BUG (should be mulxl): https://bugs.llvm.org/show_bug.cgi?id=34232 -#[cfg_attr(test, assert_instr(imul))] +#[cfg_attr(all(test, target_arch = "x86_64"), assert_instr(imul))] +#[cfg_attr(all(test, target_arch = "x86"), assert_instr(mulx))] #[target_feature = "+bmi2"] pub fn _mulx_u32(a: u32, b: u32) -> (u32, u32) { let result: u64 = (a as u64) * (b as u64); @@ -31,6 +32,7 @@ pub fn _mulx_u32(a: u32, b: u32) -> (u32, u32) { #[inline(always)] #[cfg_attr(test, assert_instr(mulx))] #[target_feature = "+bmi2"] +#[cfg(not(target_arch = "x86"))] // calls an intrinsic pub fn _mulx_u64(a: u64, b: u64) -> (u64, u64) { let result: u128 = (a as u128) * (b as u128); let hi = (result >> 64) as u64; @@ -66,6 +68,7 @@ pub fn _bzhi_u32(a: u32, index: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi2"] #[cfg_attr(test, assert_instr(bzhi))] +#[cfg(not(target_arch = "x86"))] pub fn _bzhi_u64(a: u64, index: u64) -> u64 { unsafe { x86_bmi2_bzhi_64(a, index) } } @@ -85,6 +88,7 @@ pub fn _pdep_u32(a: u32, mask: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi2"] #[cfg_attr(test, assert_instr(pdep))] +#[cfg(not(target_arch = "x86"))] pub fn _pdep_u64(a: u64, mask: u64) -> u64 { unsafe { x86_bmi2_pdep_64(a, mask) } } @@ -103,6 +107,7 @@ pub fn _pext_u32(a: u32, mask: u32) -> u32 { #[inline(always)] #[target_feature = "+bmi2"] #[cfg_attr(test, assert_instr(pext))] +#[cfg(not(target_arch = "x86"))] pub fn _pext_u64(a: u64, mask: u64) -> u64 { unsafe { x86_bmi2_pext_64(a, mask) } } diff --git a/library/stdarch/src/x86/tbm.rs b/library/stdarch/src/x86/tbm.rs index 213188536a33..8ada36815c0b 100644 --- a/library/stdarch/src/x86/tbm.rs +++ b/library/stdarch/src/x86/tbm.rs @@ -75,6 +75,7 @@ pub fn _blcfill_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blcfill))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blcfill_u64(x: u64) -> u64 { x & (x.wrapping_add(1)) } @@ -95,6 +96,7 @@ pub fn _blci_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blci))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blci_u64(x: u64) -> u64 { x | !(x.wrapping_add(1)) } @@ -115,6 +117,7 @@ pub fn _blcic_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blcic))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blcic_u64(x: u64) -> u64 { !x & (x.wrapping_add(1)) } @@ -135,6 +138,7 @@ pub fn _blcmsk_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blcmsk))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blcmsk_u64(x: u64) -> u64 { x ^ (x.wrapping_add(1)) } @@ -155,6 +159,7 @@ pub fn _blcs_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blcs))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blcs_u64(x: u64) -> u64 { x | x.wrapping_add(1) } @@ -175,6 +180,7 @@ pub fn _blsfill_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blsfill))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blsfill_u64(x: u64) -> u64 { x | (x.wrapping_sub(1)) } @@ -195,6 +201,7 @@ pub fn _blsic_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(blsic))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _blsic_u64(x: u64) -> u64 { !x | (x.wrapping_sub(1)) } @@ -217,6 +224,7 @@ pub fn _t1mskc_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(t1mskc))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _t1mskc_u64(x: u64) -> u64 { !x | (x.wrapping_add(1)) } @@ -239,6 +247,7 @@ pub fn _tzmsk_u32(x: u32) -> u32 { #[inline(always)] #[target_feature = "+tbm"] #[cfg_attr(test, assert_instr(tzmsk))] +#[cfg(not(target_arch = "x86"))] // generates lots of instructions pub fn _tzmsk_u64(x: u64) -> u64 { !x & (x.wrapping_sub(1)) }