blob: a9e6162042e2ba0fd4327835b06b99fb32632b96 [file] [edit]
//@ requireOptions("--useWasmSIMD=1")
//@ skip if !$isSIMDPlatform
import { runSIMDTests } from "./simd-instructions-lib.js"
const verbose = false;
// Table-driven test data for SIMD integer arithmetic instructions
// Each entry: [instruction, input0, input1, expected_output]
const arithmeticTests = [
// i8x16.add tests
[
"i8x16.add",
[0x01, 0x02, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0],
[0x01, 0x02, 0x01, 0x01, 0x01, 0xFF, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0],
[0x02, 0x04, 0x80, 0x81, 0x00, 0xFF, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0x00, 0x20, 0x40]
],
[
"i8x16.add",
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]
],
// i8x16.sub tests
[
"i8x16.sub",
[0x02, 0x04, 0x80, 0x81, 0x00, 0xFF, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0x00, 0x20, 0x40],
[0x01, 0x02, 0x01, 0x01, 0x01, 0xFF, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0],
[0x01, 0x02, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0]
],
[
"i8x16.sub",
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
[0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01],
[0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]
],
// i8x16.add_sat_s tests (signed saturated add)
[
"i8x16.add_sat_s",
[0x7F, 0x7E, 0x80, 0x81, 0x00, 0xFF, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x7F, 0x80, 0x81],
[0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x01, 0x01, 0x01],
[0x7F, 0x7F, 0x81, 0x82, 0x01, 0x00, 0x20, 0x40, 0x60, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x81, 0x82]
],
// i8x16.add_sat_u tests (unsigned saturated add)
[
"i8x16.add_sat_u",
[0xFF, 0xFE, 0x80, 0x81, 0x00, 0x01, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0xFF, 0xFE, 0xFD],
[0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x01, 0x02, 0x03],
[0xFF, 0xFF, 0x81, 0x82, 0x01, 0x02, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0, 0xFF, 0xFF, 0xFF]
],
// i8x16.sub_sat_s tests (signed saturated subtract)
[
"i8x16.sub_sat_s",
[0x80, 0x81, 0x7F, 0x7E, 0x00, 0xFF, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x81, 0x82],
[0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x01, 0x01, 0x01],
[0x80, 0x80, 0x7E, 0x7C, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x81]
],
// i8x16.sub_sat_u tests (unsigned saturated subtract)
[
"i8x16.sub_sat_u",
[0x00, 0x01, 0x80, 0x81, 0xFF, 0xFE, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x00, 0x01, 0x02],
[0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x01, 0x01, 0x01],
[0x00, 0x00, 0x7F, 0x80, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01]
],
// i16x8.add tests
[
"i16x8.add",
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000],
[0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0xFFFF, 0x1000, 0x2000],
[0x0002, 0x0004, 0x8000, 0x8001, 0x0000, 0xFFFF, 0x2000, 0x4000]
],
// i16x8.sub tests
[
"i16x8.sub",
[0x0002, 0x0004, 0x8000, 0x8001, 0x0000, 0xFFFF, 0x2000, 0x4000],
[0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0xFFFF, 0x1000, 0x2000],
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000]
],
// i16x8.mul tests
[
"i16x8.mul",
[0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009],
[0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009],
[0x0004, 0x0009, 0x0010, 0x0019, 0x0024, 0x0031, 0x0040, 0x0051]
],
// i16x8.add_sat_s tests (signed saturated add)
[
"i16x8.add_sat_s",
[0x7FFF, 0x7FFE, 0x8000, 0x8001, 0x0000, 0xFFFF, 0x1000, 0x7FFF],
[0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x1000, 0x0001],
[0x7FFF, 0x7FFF, 0x8001, 0x8002, 0x0001, 0x0000, 0x2000, 0x7FFF]
],
// i16x8.add_sat_u tests (unsigned saturated add)
[
"i16x8.add_sat_u",
[0xFFFF, 0xFFFE, 0x8000, 0x8001, 0x0000, 0x0001, 0x1000, 0xFFFF],
[0x0001, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x1000, 0x0001],
[0xFFFF, 0xFFFF, 0x8001, 0x8002, 0x0001, 0x0002, 0x2000, 0xFFFF]
],
// i16x8.sub_sat_s tests (signed saturated subtract)
[
"i16x8.sub_sat_s",
[0x8000, 0x8001, 0x7FFF, 0x7FFE, 0x0000, 0xFFFF, 0x1000, 0x8000],
[0x0001, 0x0001, 0x0001, 0x0002, 0x0001, 0x0001, 0x1000, 0x0001],
[0x8000, 0x8000, 0x7FFE, 0x7FFC, 0xFFFF, 0xFFFE, 0x0000, 0x8000]
],
// i16x8.sub_sat_u tests (unsigned saturated subtract)
[
"i16x8.sub_sat_u",
[0x0000, 0x0001, 0x8000, 0x8001, 0xFFFF, 0xFFFE, 0x1000, 0x0000],
[0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0002, 0x1000, 0x0001],
[0x0000, 0x0000, 0x7FFF, 0x8000, 0xFFFE, 0xFFFC, 0x0000, 0x0000]
],
// i32x4.add tests
[
"i32x4.add",
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000],
[0x00000001, 0x00000002, 0x00000001, 0x00000001],
[0x00000002, 0x00000004, 0x80000000, 0x80000001]
],
// i32x4.sub tests
[
"i32x4.sub",
[0x00000002, 0x00000004, 0x80000000, 0x80000001],
[0x00000001, 0x00000002, 0x00000001, 0x00000001],
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000]
],
// i32x4.mul tests
[
"i32x4.mul",
[0x00000002, 0x00000003, 0x00000004, 0x00000005],
[0x00000002, 0x00000003, 0x00000004, 0x00000005],
[0x00000004, 0x00000009, 0x00000010, 0x00000019]
],
// i64x2.add tests
[
"i64x2.add",
[0x0000000000000001n, 0x7FFFFFFFFFFFFFFFn],
[0x0000000000000001n, 0x0000000000000001n],
[0x0000000000000002n, 0x8000000000000000n]
],
// i64x2.sub tests
[
"i64x2.sub",
[0x0000000000000002n, 0x8000000000000000n],
[0x0000000000000001n, 0x0000000000000001n],
[0x0000000000000001n, 0x7FFFFFFFFFFFFFFFn]
],
// i64x2.mul tests - comprehensive testing including wrapping
[
"i64x2.mul",
[0x0000000000000002n, 0x0000000000000003n],
[0x0000000000000002n, 0x0000000000000003n],
[0x0000000000000004n, 0x0000000000000009n]
],
// Test wrapping behavior with large numbers
[
"i64x2.mul",
[0xFFFFFFFFFFFFFFFFn, 0x8000000000000000n],
[0x0000000000000002n, 0x0000000000000002n],
[0xFFFFFFFFFFFFFFFEn, 0x0000000000000000n] // -1 * 2 = -2 (0xFFFE...), MIN_INT64 * 2 = 0 (wraps)
],
// Test multiplication that causes overflow/wrapping
[
"i64x2.mul",
[0x0000000100000000n, 0x0000000200000000n],
[0x0000000100000000n, 0x0000000200000000n],
[0x0000000000000000n, 0x0000000000000000n] // Both overflow and wrap to 0
],
// Test with maximum positive values
[
"i64x2.mul",
[0x7FFFFFFFFFFFFFFFn, 0x0000000000000001n],
[0x0000000000000002n, 0x7FFFFFFFFFFFFFFFn],
[0xFFFFFFFFFFFFFFFEn, 0x7FFFFFFFFFFFFFFFn] // MAX_INT64 * 2 wraps to -2, 1 * MAX_INT64 = MAX_INT64
],
// Test edge case: multiply by zero
[
"i64x2.mul",
[0xFFFFFFFFFFFFFFFFn, 0x8000000000000000n],
[0x0000000000000000n, 0x0000000000000000n],
[0x0000000000000000n, 0x0000000000000000n]
],
// Test edge case: multiply by one
[
"i64x2.mul",
[0xFFFFFFFFFFFFFFFFn, 0x8000000000000000n],
[0x0000000000000001n, 0x0000000000000001n],
[0xFFFFFFFFFFFFFFFFn, 0x8000000000000000n]
],
// Test large prime numbers that will cause wrapping
[
"i64x2.mul",
[0x00000000FFFFFFFFn, 0x0000FFFFFFFFFFFFn],
[0x00000000FFFFFFFFn, 0x0000000000000010n],
[0xFFFFFFFE00000001n, 0x000FFFFFFFFFFFF0n] // Test 32-bit and 48-bit boundary cases
],
// i8x16.min_s tests (signed minimum)
[
"i8x16.min_s",
[0x01, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0],
[0x02, 0x80, 0x7F, 0x00, 0xFF, 0x20, 0x10, 0x40, 0x30, 0x60, 0x50, 0x80, 0x70, 0xA0, 0x90, 0xC0],
[0x01, 0x80, 0x80, 0xFF, 0xFF, 0x10, 0x10, 0x30, 0x30, 0x50, 0x50, 0x80, 0x80, 0x90, 0x90, 0xB0]
],
// i8x16.min_u tests (unsigned minimum)
[
"i8x16.min_u",
[0x01, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0],
[0x02, 0x80, 0x7F, 0x00, 0xFF, 0x20, 0x10, 0x40, 0x30, 0x60, 0x50, 0x80, 0x70, 0xA0, 0x90, 0xC0],
[0x01, 0x7F, 0x7F, 0x00, 0x00, 0x10, 0x10, 0x30, 0x30, 0x50, 0x50, 0x70, 0x70, 0x90, 0x90, 0xB0]
],
// i8x16.max_s tests (signed maximum)
[
"i8x16.max_s",
[0x01, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0],
[0x02, 0x80, 0x7F, 0x00, 0xFF, 0x20, 0x10, 0x40, 0x30, 0x60, 0x50, 0x80, 0x70, 0xA0, 0x90, 0xC0],
[0x02, 0x7F, 0x7F, 0x00, 0x00, 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x70, 0x70, 0xA0, 0xA0, 0xC0]
],
// i8x16.max_u tests (unsigned maximum)
[
"i8x16.max_u",
[0x01, 0x7F, 0x80, 0xFF, 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0],
[0x02, 0x80, 0x7F, 0x00, 0xFF, 0x20, 0x10, 0x40, 0x30, 0x60, 0x50, 0x80, 0x70, 0xA0, 0x90, 0xC0],
[0x02, 0x80, 0x80, 0xFF, 0xFF, 0x20, 0x20, 0x40, 0x40, 0x60, 0x60, 0x80, 0x80, 0xA0, 0xA0, 0xC0]
],
// i16x8.min_s tests (signed minimum)
[
"i16x8.min_s",
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000],
[0x0002, 0x0001, 0x8000, 0x7FFF, 0x0000, 0xFFFF, 0x2000, 0x1000],
[0x0001, 0x0001, 0x8000, 0x8000, 0xFFFF, 0xFFFF, 0x1000, 0x1000]
],
// i16x8.min_u tests (unsigned minimum)
[
"i16x8.min_u",
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000],
[0x0002, 0x0001, 0x8000, 0x7FFF, 0x0000, 0xFFFF, 0x2000, 0x1000],
[0x0001, 0x0001, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x1000, 0x1000]
],
// i16x8.max_s tests (signed maximum)
[
"i16x8.max_s",
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000],
[0x0002, 0x0001, 0x8000, 0x7FFF, 0x0000, 0xFFFF, 0x2000, 0x1000],
[0x0002, 0x0002, 0x7FFF, 0x7FFF, 0x0000, 0x0000, 0x2000, 0x2000]
],
// i16x8.max_u tests (unsigned maximum)
[
"i16x8.max_u",
[0x0001, 0x0002, 0x7FFF, 0x8000, 0xFFFF, 0x0000, 0x1000, 0x2000],
[0x0002, 0x0001, 0x8000, 0x7FFF, 0x0000, 0xFFFF, 0x2000, 0x1000],
[0x0002, 0x0002, 0x8000, 0x8000, 0xFFFF, 0xFFFF, 0x2000, 0x2000]
],
// i32x4.min_s tests (signed minimum)
[
"i32x4.min_s",
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000001, 0x80000000, 0x7FFFFFFF],
[0x00000001, 0x00000001, 0x80000000, 0x80000000]
],
// i32x4.min_u tests (unsigned minimum)
[
"i32x4.min_u",
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000001, 0x80000000, 0x7FFFFFFF],
[0x00000001, 0x00000001, 0x7FFFFFFF, 0x7FFFFFFF]
],
// i32x4.max_s tests (signed maximum)
[
"i32x4.max_s",
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000001, 0x80000000, 0x7FFFFFFF],
[0x00000002, 0x00000002, 0x7FFFFFFF, 0x7FFFFFFF]
],
// i32x4.max_u tests (unsigned maximum)
[
"i32x4.max_u",
[0x00000001, 0x00000002, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000001, 0x80000000, 0x7FFFFFFF],
[0x00000002, 0x00000002, 0x80000000, 0x80000000]
],
// i8x16.abs tests (absolute value of signed 8-bit integers)
[
"i8x16.abs",
[0x00, 0x01, 0x7F, 0x80, 0x81, 0xFF, 0x10, 0xF0, 0x20, 0xE0, 0x30, 0xD0, 0x40, 0xC0, 0x50, 0xB0],
[0x00, 0x01, 0x7F, 0x80, 0x7F, 0x01, 0x10, 0x10, 0x20, 0x20, 0x30, 0x30, 0x40, 0x40, 0x50, 0x50]
],
// i8x16.neg tests (negate 8-bit integers)
[
"i8x16.neg",
[0x00, 0x01, 0x7F, 0x80, 0x81, 0xFF, 0x10, 0xF0, 0x20, 0xE0, 0x30, 0xD0, 0x40, 0xC0, 0x50, 0xB0],
[0x00, 0xFF, 0x81, 0x80, 0x7F, 0x01, 0xF0, 0x10, 0xE0, 0x20, 0xD0, 0x30, 0xC0, 0x40, 0xB0, 0x50]
],
// i16x8.abs tests (absolute value of signed 16-bit integers)
[
"i16x8.abs",
[0x0000, 0x0001, 0x7FFF, 0x8000, 0x8001, 0xFFFF, 0x1000, 0xF000],
[0x0000, 0x0001, 0x7FFF, 0x8000, 0x7FFF, 0x0001, 0x1000, 0x1000]
],
// i16x8.neg tests (negate 16-bit integers)
[
"i16x8.neg",
[0x0000, 0x0001, 0x7FFF, 0x8000, 0x8001, 0xFFFF, 0x1000, 0xF000],
[0x0000, 0xFFFF, 0x8001, 0x8000, 0x7FFF, 0x0001, 0xF000, 0x1000]
],
// i32x4.abs tests (absolute value of signed 32-bit integers)
[
"i32x4.abs",
[0x00000000, 0x00000001, 0x7FFFFFFF, 0x80000000],
[0x00000000, 0x00000001, 0x7FFFFFFF, 0x80000000]
],
// i32x4.neg tests (negate 32-bit integers)
[
"i32x4.neg",
[0x00000000, 0x00000001, 0x7FFFFFFF, 0x80000000],
[0x00000000, 0xFFFFFFFF, 0x80000001, 0x80000000]
],
// i64x2.abs tests (absolute value of signed 64-bit integers)
[
"i64x2.abs",
[0x0000000000000000n, 0x7FFFFFFFFFFFFFFFn],
[0x0000000000000000n, 0x7FFFFFFFFFFFFFFFn]
],
// i64x2.neg tests (negate 64-bit integers)
[
"i64x2.neg",
[0x0000000000000000n, 0x7FFFFFFFFFFFFFFFn],
[0x0000000000000000n, 0x8000000000000001n]
],
// i16x8.extend_low_i8x16_s - sign-extend lower 8 i8 values to i16
[
"i16x8.extend_low_i8x16_s",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x32, 0xCE, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10],
[0x0001, 0xFFFF, 0x007F, 0xFF80, 0x0000, 0x0032, 0xFFCE, 0x0064] // 0xFF=-1, 0x80=-128, 0xCE=-50 sign-extended
],
[
"i16x8.extend_low_i8x16_s",
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000]
],
// i16x8.extend_high_i8x16_s - sign-extend upper 8 i8 values to i16
[
"i16x8.extend_high_i8x16_s",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x32, 0xCE, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10],
[0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010]
],
[
"i16x8.extend_high_i8x16_s",
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000]
],
// i16x8.extend_low_i8x16_u - zero-extend lower 8 i8 values to i16
[
"i16x8.extend_low_i8x16_u",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x32, 0xC8, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10],
[0x0001, 0x00FF, 0x007F, 0x0080, 0x0000, 0x0032, 0x00C8, 0x0064] // Zero-extended
],
[
"i16x8.extend_low_i8x16_u",
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000]
],
// i16x8.extend_high_i8x16_u - zero-extend upper 8 i8 values to i16
[
"i16x8.extend_high_i8x16_u",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x32, 0xC8, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10],
[0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010]
],
[
"i16x8.extend_high_i8x16_u",
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000]
],
// i32x4.extend_low_i16x8_s - sign-extend lower 4 i16 values to i32
[
"i32x4.extend_low_i16x8_s",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x03E8, 0xEA60, 0x1388],
[0x00000001, 0xFFFFFFFF, 0x00007FFF, 0xFFFF8000] // 0xFFFF=-1, 0x8000=-32768 sign-extended
],
[
"i32x4.extend_low_i16x8_s",
[0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF],
[0x00000000, 0x00000000, 0x00000000, 0x00000000]
],
// i32x4.extend_high_i16x8_s - sign-extend upper 4 i16 values to i32
[
"i32x4.extend_high_i16x8_s",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x03E8, 0xEA60, 0x1388],
[0x00000000, 0x000003E8, 0xFFFFEA60, 0x00001388] // 0xEA60=-5536 sign-extended to 0xFFFFEA60
],
[
"i32x4.extend_high_i16x8_s",
[0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000],
[0x00000000, 0x00000000, 0x00000000, 0x00000000]
],
// i32x4.extend_low_i16x8_u - zero-extend lower 4 i16 values to i32
[
"i32x4.extend_low_i16x8_u",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x03E8, 0xEA60, 0x1388],
[0x00000001, 0x0000FFFF, 0x00007FFF, 0x00008000] // Zero-extended
],
[
"i32x4.extend_low_i16x8_u",
[0x0000, 0x0000, 0x0000, 0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF],
[0x00000000, 0x00000000, 0x00000000, 0x00000000]
],
// i32x4.extend_high_i16x8_u - zero-extend upper 4 i16 values to i32
[
"i32x4.extend_high_i16x8_u",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x03E8, 0xEA60, 0x1388],
[0x00000000, 0x000003E8, 0x0000EA60, 0x00001388] // Zero-extended
],
[
"i32x4.extend_high_i16x8_u",
[0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0000, 0x0000],
[0x00000000, 0x00000000, 0x00000000, 0x00000000]
],
// i64x2.extend_low_i32x4_s - sign-extend lower 2 i32 values to i64
[
"i64x2.extend_low_i32x4_s",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x0000000000000001n, 0xFFFFFFFFFFFFFFFFn]
],
[
"i64x2.extend_low_i32x4_s",
[0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF],
[0x0000000000000000n, 0x0000000000000000n]
],
// i64x2.extend_high_i32x4_s - sign-extend upper 2 i32 values to i64
[
"i64x2.extend_high_i32x4_s",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x000000007FFFFFFFn, 0xFFFFFFFF80000000n]
],
[
"i64x2.extend_high_i32x4_s",
[0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000],
[0x0000000000000000n, 0x0000000000000000n]
],
// i64x2.extend_low_i32x4_u - zero-extend lower 2 i32 values to i64
[
"i64x2.extend_low_i32x4_u",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x0000000000000001n, 0x00000000FFFFFFFFn] // Zero-extended
],
[
"i64x2.extend_low_i32x4_u",
[0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF],
[0x0000000000000000n, 0x0000000000000000n]
],
// i64x2.extend_high_i32x4_u - zero-extend upper 2 i32 values to i64
[
"i64x2.extend_high_i32x4_u",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x000000007FFFFFFFn, 0x0000000080000000n] // Zero-extended
],
[
"i64x2.extend_high_i32x4_u",
[0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000],
[0x0000000000000000n, 0x0000000000000000n]
],
// i8x16.narrow_i16x8_s - narrow 2 i16x8 vectors to 1 i8x16 vector with signed saturation
[
"i8x16.narrow_i16x8_s",
[0x0001, 0x007F, 0x0080, 0xFF80, 0x0000, 0x0032, 0xFFCE, 0x0064],
[0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010],
[0x01, 0x7F, 0x7F, 0x80, 0x00, 0x32, 0xCE, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]
],
[
"i8x16.narrow_i16x8_s",
[0x0100, 0xFF00, 0x7FFF, 0x8000, 0x0000, 0x0001, 0xFFFF, 0x0002], // Values that saturate
[0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A],
[0x7F, 0x80, 0x7F, 0x80, 0x00, 0x01, 0xFF, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A] // Saturated values
],
// i8x16.narrow_i16x8_u - narrow 2 i16x8 vectors to 1 i8x16 vector with unsigned saturation
[
"i8x16.narrow_i16x8_u",
[0x0001, 0x00FF, 0x0100, 0xFF80, 0x0000, 0x0032, 0xFFCE, 0x0064],
[0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, 0x0010],
[0x01, 0xFF, 0xFF, 0x00, 0x00, 0x32, 0x00, 0x64, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10]
],
[
"i8x16.narrow_i16x8_u",
[0x0200, 0xFF00, 0x7FFF, 0x8000, 0x0000, 0x0001, 0xFFFF, 0x0002], // Values that saturate
[0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A],
[0xFF, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A] // Saturated values
],
// i16x8.narrow_i32x4_s - narrow 2 i32x4 vectors to 1 i16x8 vector with signed saturation
[
"i16x8.narrow_i32x4_s",
[0x00000001, 0x00007FFF, 0x00008000, 0xFFFF8000],
[0x00000000, 0x00000032, 0xFFFFFFCE, 0x00000064],
[0x0001, 0x7FFF, 0x7FFF, 0x8000, 0x0000, 0x0032, 0xFFCE, 0x0064]
],
[
"i16x8.narrow_i32x4_s",
[0x00010000, 0xFFFF0000, 0x7FFFFFFF, 0x80000000], // Values that saturate
[0x00000001, 0x00000002, 0xFFFFFFFF, 0x00000003],
[0x7FFF, 0x8000, 0x7FFF, 0x8000, 0x0001, 0x0002, 0xFFFF, 0x0003] // Saturated values
],
// i16x8.narrow_i32x4_u - narrow 2 i32x4 vectors to 1 i16x8 vector with unsigned saturation
[
"i16x8.narrow_i32x4_u",
[0x00000001, 0x0000FFFF, 0x00010000, 0xFFFF8000],
[0x00000000, 0x00000032, 0xFFFFFFCE, 0x00000064],
[0x0001, 0xFFFF, 0xFFFF, 0x0000, 0x0000, 0x0032, 0x0000, 0x0064]
],
[
"i16x8.narrow_i32x4_u",
[0x00020000, 0xFFFF0000, 0x7FFFFFFF, 0x80000000], // Values that saturate
[0x00000001, 0x00000002, 0xFFFFFFFF, 0x00000003],
[0xFFFF, 0x0000, 0xFFFF, 0x0000, 0x0001, 0x0002, 0x0000, 0x0003] // Saturated values
],
// i16x8.extmul_low_i8x16_s - multiply lower 8 i8 elements and extend to i16
[
"i16x8.extmul_low_i8x16_s",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x02, 0xFE, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C],
[0x02, 0x03, 0x02, 0x02, 0x01, 0x03, 0x02, 0x05, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14],
[0x0002, 0xFFFD, 0x00FE, 0xFF00, 0x0000, 0x0006, 0xFFFC, 0x0014] // Result i16x8: 1*2=2, -1*3=-3, 127*2=254, -128*2=-256, 0*1=0, 2*3=6, -2*2=-4, 4*5=20
],
[
"i16x8.extmul_low_i8x16_s",
[0x10, 0xF0, 0x20, 0xE0, 0x30, 0xD0, 0x40, 0xC0, 0x50, 0xB0, 0x60, 0xA0, 0x70, 0x90, 0x7F, 0x81], // Edge cases
[0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09],
[0x0020, 0xFFE0, 0x0060, 0xFFA0, 0x00C0, 0xFF40, 0x0140, 0xFEC0] // 16*2=32, -16*2=-32, 32*3=96, -32*3=-96, 48*4=192, -48*4=-192, 64*5=320, -64*5=-320
],
// i16x8.extmul_high_i8x16_s - multiply upper 8 i8 elements and extend to i16
[
"i16x8.extmul_high_i8x16_s",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x02, 0xFE, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C],
[0x02, 0x03, 0x02, 0x02, 0x01, 0x03, 0x02, 0x05, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14],
[0x0041, 0x0054, 0x0069, 0x0080, 0x0099, 0x00B4, 0x00D1, 0x00F0] // Result i16x8: 5*13=65, 6*14=84, 7*15=105, 8*16=128, 9*17=153, 10*18=180, 11*19=209, 12*20=240
],
// i16x8.extmul_low_i8x16_u - multiply lower 8 i8 elements (unsigned) and extend to i16
[
"i16x8.extmul_low_i8x16_u",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x02, 0xFE, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C],
[0x02, 0x03, 0x02, 0x02, 0x01, 0x03, 0x02, 0x05, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14],
[0x0002, 0x02FD, 0x00FE, 0x0100, 0x0000, 0x0006, 0x01FC, 0x0014] // Result i16x8: 1*2=2, 255*3=765, 127*2=254, 128*2=256, 0*1=0, 2*3=6, 254*2=508, 4*5=20
],
// i16x8.extmul_high_i8x16_u - multiply upper 8 i8 elements (unsigned) and extend to i16
[
"i16x8.extmul_high_i8x16_u",
[0x01, 0xFF, 0x7F, 0x80, 0x00, 0x02, 0xFE, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C],
[0x02, 0x03, 0x02, 0x02, 0x01, 0x03, 0x02, 0x05, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14],
[0x0041, 0x0054, 0x0069, 0x0080, 0x0099, 0x00B4, 0x00D1, 0x00F0] // Result i16x8: 5*13=65, 6*14=84, 7*15=105, 8*16=128, 9*17=153, 10*18=180, 11*19=209, 12*20=240
],
// i32x4.extmul_low_i16x8_s - multiply lower 4 i16 elements and extend to i32
[
"i32x4.extmul_low_i16x8_s",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x0002, 0xFFFE, 0x0004],
[0x0002, 0x0003, 0x0002, 0x0002, 0x0001, 0x0003, 0x0002, 0x0005],
[0x00000002, 0xFFFFFFFD, 0x0000FFFE, 0xFFFF0000] // Result i32x4: 1*2=2, -1*3=-3, 32767*2=65534, -32768*2=-65536
],
[
"i32x4.extmul_low_i16x8_s",
[0x0100, 0xFF00, 0x0200, 0xFE00, 0x0300, 0xFD00, 0x0400, 0xFC00], // Larger values
[0x0002, 0x0002, 0x0003, 0x0003, 0x0004, 0x0004, 0x0005, 0x0005],
[0x00000200, 0xFFFFFE00, 0x00000600, 0xFFFFFA00] // 256*2=512, -256*2=-512, 512*3=1536, -512*3=-1536
],
// i32x4.extmul_high_i16x8_s - multiply upper 4 i16 elements and extend to i32
[
"i32x4.extmul_high_i16x8_s",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x0002, 0xFFFE, 0x0004],
[0x0002, 0x0003, 0x0002, 0x0002, 0x0001, 0x0003, 0x0002, 0x0005],
[0x00000000, 0x00000006, 0xFFFFFFFC, 0x00000014] // Result i32x4: 0*1=0, 2*3=6, -2*2=-4, 4*5=20
],
// i32x4.extmul_low_i16x8_u - multiply lower 4 i16 elements (unsigned) and extend to i32
[
"i32x4.extmul_low_i16x8_u",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x0002, 0xFFFE, 0x0004],
[0x0002, 0x0003, 0x0002, 0x0002, 0x0001, 0x0003, 0x0002, 0x0005],
[0x00000002, 0x0002FFFD, 0x0000FFFE, 0x00010000] // Result i32x4: 1*2=2, 65535*3=196605, 32767*2=65534, 32768*2=65536
],
// i32x4.extmul_high_i16x8_u - multiply upper 4 i16 elements (unsigned) and extend to i32
[
"i32x4.extmul_high_i16x8_u",
[0x0001, 0xFFFF, 0x7FFF, 0x8000, 0x0000, 0x0002, 0xFFFE, 0x0004],
[0x0002, 0x0003, 0x0002, 0x0002, 0x0001, 0x0003, 0x0002, 0x0005],
[0x00000000, 0x00000006, 0x0001FFFC, 0x00000014] // Result i32x4: 0*1=0, 2*3=6, 65534*2=131068, 4*5=20
],
// i64x2.extmul_low_i32x4_s - multiply lower 2 i32 elements and extend to i64
[
"i64x2.extmul_low_i32x4_s",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000003, 0x00000002, 0x00000002],
[0x0000000000000002n, 0xFFFFFFFFFFFFFFFDn] // Result i64x2: 1*2=2, -1*3=-3
],
[
"i64x2.extmul_low_i32x4_s",
[0x00010000, 0xFFFF0000, 0x00020000, 0xFFFE0000], // Larger values
[0x00000002, 0x00000002, 0x00000003, 0x00000003],
[0x0000000000020000n, 0xFFFFFFFFFFFE0000n] // 65536*2=131072, -65536*2=-131072
],
// i64x2.extmul_high_i32x4_s - multiply upper 2 i32 elements and extend to i64
[
"i64x2.extmul_high_i32x4_s",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000003, 0x00000002, 0x00000002],
[0x00000000FFFFFFFEn, 0xFFFFFFFF00000000n] // Result i64x2: 2147483647*2=4294967294, -2147483648*2=-4294967296
],
// i64x2.extmul_low_i32x4_u - multiply lower 2 i32 elements (unsigned) and extend to i64
[
"i64x2.extmul_low_i32x4_u",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000], // First i32x4
[0x00000002, 0x00000003, 0x00000002, 0x00000002], // Second i32x4
[0x0000000000000002n, 0x00000002FFFFFFFDn] // Result i64x2: 1*2=2, 4294967295*3=12884901885
],
// i64x2.extmul_high_i32x4_u - multiply upper 2 i32 elements (unsigned) and extend to i64
[
"i64x2.extmul_high_i32x4_u",
[0x00000001, 0xFFFFFFFF, 0x7FFFFFFF, 0x80000000],
[0x00000002, 0x00000003, 0x00000002, 0x00000002],
[0x00000000FFFFFFFEn, 0x0000000100000000n] // Result i64x2: 2147483647*2=4294967294, 2147483648*2=4294967296
],
// i8x16.avgr_u - average of 16 8-bit unsigned integers with rounding
[
"i8x16.avgr_u",
[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f],
[0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f],
[0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17]
],
// i16x8.avgr_u - average of 8 16-bit unsigned integers with rounding
[
"i16x8.avgr_u",
[0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008],
[0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080],
[0x0009, 0x0011, 0x001a, 0x0022, 0x002b, 0x0033, 0x003c, 0x0044]
],
// i16x8.extadd_pairwise_i8x16_s - pairwise addition of signed 8-bit integers to 16-bit
[
"i16x8.extadd_pairwise_i8x16_s",
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x80, 0x7f, 0x81, 0x7e, 0x82, 0x7d, 0x83, 0x7c],
[0x0003, 0x0007, 0x000b, 0x000f, 0xffff, 0xffff, 0xffff, 0xffff]
],
// i16x8.extadd_pairwise_i8x16_u - pairwise addition of unsigned 8-bit integers to 16-bit
[
"i16x8.extadd_pairwise_i8x16_u",
[0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x80, 0x7f, 0x81, 0x7e, 0x82, 0x7d, 0x83, 0x7c],
[0x0003, 0x0007, 0x000b, 0x000f, 0x00ff, 0x00ff, 0x00ff, 0x00ff]
],
// i32x4.extadd_pairwise_i16x8_s - pairwise addition of signed 16-bit integers to 32-bit
[
"i32x4.extadd_pairwise_i16x8_s",
[0x0001, 0x0002, 0x0003, 0x0004, 0x8000, 0x7fff, 0x8001, 0x7ffe],
[0x00000003, 0x00000007, 0xffffffff, 0xffffffff]
],
// i32x4.extadd_pairwise_i16x8_u - pairwise addition of unsigned 16-bit integers to 32-bit
[
"i32x4.extadd_pairwise_i16x8_u",
[0x0001, 0x0002, 0x0003, 0x0004, 0x8000, 0x7fff, 0x8001, 0x7ffe],
[0x00000003, 0x00000007, 0x0000ffff, 0x0000ffff]
],
// i16x8.q15mulr_sat_s - Q15 multiply with rounding and saturation
[
"i16x8.q15mulr_sat_s",
[0x4000, 0x2000, 0x1000, 0x0800, 0x7fff, 0x7fff, 0x8000, 0x8001],
[0x4000, 0x2000, 0x1000, 0x0800, 0x7fff, 0x0001, 0x8000, 0x7fff],
[0x2000, 0x0800, 0x0200, 0x0080, 0x7ffe, 0x0001, 0x7fff, 0x8002]
],
// i32x4.dot_i16x8_s - dot product of signed 16-bit integers to 32-bit
[
"i32x4.dot_i16x8_s",
[0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008],
[0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008],
[0x00000005, 0x00000019, 0x0000003D, 0x00000071]
]
];
await runSIMDTests(arithmeticTests, verbose, "SIMD integer arithmetic");