Skip to content
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

Uncomment wasm32 bitmask instruction #1004

Closed
wants to merge 12 commits into from
16 changes: 14 additions & 2 deletions ci/docker/wasm32-wasi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,20 @@ RUN apt-get update -y && apt-get install -y --no-install-recommends \
xz-utils \
clang

RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/v0.22.1/wasmtime-v0.22.1-x86_64-linux.tar.xz | tar xJf -
ENV PATH=$PATH:/wasmtime-v0.22.1-x86_64-linux
#ENV WASMER_DIR="/.wasmer"

#RUN curl https://get.wasmer.io -sSfL | sh

#ENV PATH="$PATH:/.wasmer:/.wasmer/bin"

#ENV CARGO_TARGET_WASM32_WASI_RUNNER="wasmer run \
# --llvm \
# --enable-simd \
# --mapdir .::/checkout/target/wasm32-wasi/release/deps \
# --"

RUN curl -L https://github.com/bytecodealliance/wasmtime/releases/download/dev/wasmtime-dev-x86_64-linux.tar.xz | tar xJf -
ENV PATH=$PATH:/wasmtime-dev-x86_64-linux

ENV CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime \
--enable-simd \
Expand Down
108 changes: 80 additions & 28 deletions crates/core_arch/src/wasm32/simd128.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ extern "C" {
fn llvm_widen_low_i32x4_u(a: i16x8) -> i32x4;
#[link_name = "llvm.wasm.widen.high.unsigned.v4i32.v8i16"]
fn llvm_widen_high_i32x4_u(a: i16x8) -> i32x4;

//#[link_name = "llvm.wasm.bitmask.v2i64"]
//fn llvm_bitmask_i64x2(a: i64x2) -> i32;
}

/// Loads a `v128` vector from the given heap address.
Expand Down Expand Up @@ -1416,7 +1419,7 @@ pub unsafe fn v128_bitselect(v1: v128, v2: v128, c: v128) -> v128 {

/// Lane-wise wrapping absolute value.
#[inline]
// #[cfg_attr(test, assert_instr(i8x16.abs))] // FIXME support not in our LLVM yet
#[cfg_attr(test, assert_instr(i8x16.abs))]
#[target_feature(enable = "simd128")]
pub unsafe fn i8x16_abs(a: v128) -> v128 {
let a = transmute::<_, i8x16>(a);
Expand Down Expand Up @@ -1452,14 +1455,14 @@ pub unsafe fn i8x16_all_true(a: v128) -> i32 {
llvm_i8x16_all_true(a.as_i8x16())
}

// FIXME: not available in our LLVM yet
// /// Extracts the high bit for each lane in `a` and produce a scalar mask with
// /// all bits concatenated.
// #[inline]
// #[cfg_attr(test, assert_instr(i8x16.all_true))]
// pub unsafe fn i8x16_bitmask(a: v128) -> i32 {
// llvm_bitmask_i8x16(transmute(a))
// }
/// Extracts the high bit for each lane in `a` and produce a scalar mask with
/// all bits concatenated.
#[inline]
#[cfg_attr(test, assert_instr(i8x16.bitmask))]
#[target_feature(enable = "simd128")]
pub unsafe fn i8x16_bitmask(a: v128) -> i32 {
llvm_bitmask_i8x16(transmute(a))
}

/// Converts two input vectors into a smaller lane vector by narrowing each
/// lane.
Expand Down Expand Up @@ -1626,7 +1629,7 @@ pub unsafe fn i8x16_avgr_u(a: v128, b: v128) -> v128 {

/// Lane-wise wrapping absolute value.
#[inline]
// #[cfg_attr(test, assert_instr(i16x8.abs))] // FIXME support not in our LLVM yet
#[cfg_attr(test, assert_instr(i16x8.abs))]
#[target_feature(enable = "simd128")]
pub unsafe fn i16x8_abs(a: v128) -> v128 {
let a = transmute::<_, i16x8>(a);
Expand Down Expand Up @@ -1662,14 +1665,14 @@ pub unsafe fn i16x8_all_true(a: v128) -> i32 {
llvm_i16x8_all_true(a.as_i16x8())
}

// FIXME: not available in our LLVM yet
// /// Extracts the high bit for each lane in `a` and produce a scalar mask with
// /// all bits concatenated.
// #[inline]
// #[cfg_attr(test, assert_instr(i16x8.all_true))]
// pub unsafe fn i16x8_bitmask(a: v128) -> i32 {
// llvm_bitmask_i16x8(transmute(a))
// }
/// Extracts the high bit for each lane in `a` and produce a scalar mask with
/// all bits concatenated.
#[inline]
#[cfg_attr(test, assert_instr(i16x8.bitmask))]
#[target_feature(enable = "simd128")]
pub unsafe fn i16x8_bitmask(a: v128) -> i32 {
llvm_bitmask_i16x8(transmute(a))
}

/// Converts two input vectors into a smaller lane vector by narrowing each
/// lane.
Expand Down Expand Up @@ -1877,7 +1880,7 @@ pub unsafe fn i16x8_avgr_u(a: v128, b: v128) -> v128 {

/// Lane-wise wrapping absolute value.
#[inline]
// #[cfg_attr(test, assert_instr(i32x4.abs))] // FIXME support not in our LLVM yet
#[cfg_attr(test, assert_instr(i32x4.abs))]
#[target_feature(enable = "simd128")]
pub unsafe fn i32x4_abs(a: v128) -> v128 {
let a = transmute::<_, i32x4>(a);
Expand Down Expand Up @@ -1913,14 +1916,14 @@ pub unsafe fn i32x4_all_true(a: v128) -> i32 {
llvm_i32x4_all_true(a.as_i32x4())
}

// FIXME: not available in our LLVM yet
// /// Extracts the high bit for each lane in `a` and produce a scalar mask with
// /// all bits concatenated.
// #[inline]
// #[cfg_attr(test, assert_instr(i32x4.all_true))]
// pub unsafe fn i32x4_bitmask(a: v128) -> i32 {
// llvm_bitmask_i32x4(transmute(a))
// }
/// Extracts the high bit for each lane in `a` and produce a scalar mask with
/// all bits concatenated.
#[inline]
#[cfg_attr(test, assert_instr(i32x4.bitmask))]
#[target_feature(enable = "simd128")]
pub unsafe fn i32x4_bitmask(a: v128) -> i32 {
llvm_bitmask_i32x4(transmute(a))
}

/// Converts low half of the smaller lane vector to a larger lane
/// vector, sign extended.
Expand Down Expand Up @@ -2119,12 +2122,21 @@ pub unsafe fn i64x2_sub(a: v128, b: v128) -> v128 {

/// Multiplies two 128-bit vectors as if they were two packed two 64-bit integers.
#[inline]
// #[cfg_attr(test, assert_instr(i64x2.mul))] // FIXME: not present in our LLVM
#[cfg_attr(test, assert_instr(i64x2.mul))]
#[target_feature(enable = "simd128")]
pub unsafe fn i64x2_mul(a: v128, b: v128) -> v128 {
transmute(simd_mul(a.as_i64x2(), b.as_i64x2()))
}

/*/// Extracts the high bit for each lane in `a` and produce a scalar mask with
/// all bits concatenated.
#[inline]
#[cfg_attr(test, assert_instr(i64x2.bitmask))]
#[target_feature(enable = "simd128")]
pub unsafe fn i64x2_bitmask(a: v128) -> i32 {
llvm_bitmask_i64x2(transmute(a))
}*/

/// Calculates the absolute value of each lane of a 128-bit vector interpreted
/// as four 32-bit floating point numbers.
#[inline]
Expand Down Expand Up @@ -2806,6 +2818,46 @@ pub mod tests {
}
}

#[test]
fn test_bitmask_ops() {
unsafe {
let a: [u32; 4] = [u32::MAX, 0, u32::MAX, 0];
let b: [u32; 4] = [u32::MAX; 4];
let c: [u32; 4] = [0; 4];

let vec_a: v128 = transmute(a);
let vec_b: v128 = transmute(b);
let vec_c: v128 = transmute(c);

let r: i32 = i8x16_bitmask(vec_a);
assert_eq!(r, 0b1111000011110000);
let r: i32 = i16x8_bitmask(vec_a);
assert_eq!(r, 0b11001100);
let r: i32 = i32x4_bitmask(vec_a);
assert_eq!(r, 0b1010);
/*let r: i32 = i64x2_bitmask(vec_a);
assert_eq!(r, 0b11);*/

let r: i32 = i8x16_bitmask(vec_b);
assert_eq!(r, 0xFFFF);
let r: i32 = i16x8_bitmask(vec_b);
assert_eq!(r, 0xFF);
let r: i32 = i32x4_bitmask(vec_b);
assert_eq!(r, 0xF);
/*let r: i32 = i64x2_bitmask(vec_b);
assert_eq!(r, 0b11);*/

let r: i32 = i8x16_bitmask(vec_c);
assert_eq!(r, 0);
let r: i32 = i16x8_bitmask(vec_c);
assert_eq!(r, 0);
let r: i32 = i32x4_bitmask(vec_c);
assert_eq!(r, 0);
/*let r: i32 = i64x2_bitmask(vec_c);
assert_eq!(r, 0);*/
}
}

macro_rules! test_bool_red {
([$test_id:ident, $any:ident, $all:ident] | [$($true:expr),*] | [$($false:expr),*] | [$($alt:expr),*]) => {
#[test]
Expand Down