Skip to content

Commit c75757d

Browse files
authored
[wasm] PackedSimd, add floating point methods (#85705)
* [wasm] PackedSimd, add floating point methods * Fix pmax/pmin
1 parent 4679e59 commit c75757d

File tree

9 files changed

+379
-91
lines changed

9 files changed

+379
-91
lines changed

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.PlatformNotSupported.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,57 @@ public abstract class PackedSimd
392392
public static Vector128<nint> CompareGreaterThanOrEqual(Vector128<nint> left, Vector128<nint> right) { throw new PlatformNotSupportedException(); }
393393
public static Vector128<nuint> CompareGreaterThanOrEqual(Vector128<nuint> left, Vector128<nuint> right) { throw new PlatformNotSupportedException(); }
394394

395+
// Floating-point sign bit operations
396+
397+
public static Vector128<float> Negate(Vector128<float> value) { throw new PlatformNotSupportedException(); }
398+
public static Vector128<double> Negate(Vector128<double> value) { throw new PlatformNotSupportedException(); }
399+
400+
public static Vector128<float> Abs(Vector128<float> value) { throw new PlatformNotSupportedException(); }
401+
public static Vector128<double> Abs(Vector128<double> value) { throw new PlatformNotSupportedException(); }
402+
403+
// Floating-point min and max
404+
405+
public static Vector128<float> Min(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
406+
public static Vector128<double> Min(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
407+
408+
public static Vector128<float> Max(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
409+
public static Vector128<double> Max(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
410+
411+
public static Vector128<float> PseudoMin(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
412+
public static Vector128<double> PseudoMin(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
413+
414+
public static Vector128<float> PseudoMax(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
415+
public static Vector128<double> PseudoMax(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
416+
417+
// Floating-point arithmetic
418+
419+
public static Vector128<float> Add(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
420+
public static Vector128<double> Add(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
421+
422+
public static Vector128<float> Subtract(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
423+
public static Vector128<double> Subtract(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
424+
425+
public static Vector128<float> Divide(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
426+
public static Vector128<double> Divide(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
427+
428+
public static Vector128<float> Multiply(Vector128<float> left, Vector128<float> right) { throw new PlatformNotSupportedException(); }
429+
public static Vector128<double> Multiply(Vector128<double> left, Vector128<double> right) { throw new PlatformNotSupportedException(); }
430+
431+
public static Vector128<float> Sqrt(Vector128<float> value) { throw new PlatformNotSupportedException(); }
432+
public static Vector128<double> Sqrt(Vector128<double> value) { throw new PlatformNotSupportedException(); }
433+
434+
public static Vector128<float> Ceiling(Vector128<float> value) { throw new PlatformNotSupportedException(); }
435+
public static Vector128<double> Ceiling(Vector128<double> value) { throw new PlatformNotSupportedException(); }
436+
437+
public static Vector128<float> Floor(Vector128<float> value) { throw new PlatformNotSupportedException(); }
438+
public static Vector128<double> Floor(Vector128<double> value) { throw new PlatformNotSupportedException(); }
439+
440+
public static Vector128<float> Truncate(Vector128<float> value) { throw new PlatformNotSupportedException(); }
441+
public static Vector128<double> Truncate(Vector128<double> value) { throw new PlatformNotSupportedException(); }
442+
443+
public static Vector128<float> RoundToNearest(Vector128<float> value) { throw new PlatformNotSupportedException(); }
444+
public static Vector128<double> RoundToNearest(Vector128<double> value) { throw new PlatformNotSupportedException(); }
445+
395446
// Conversions
396447

397448
internal static Vector128<sbyte> ConvertNarrowingSignedSaturate(Vector128<short> lower, Vector128<short> upper) { throw new PlatformNotSupportedException(); }

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Wasm/PackedSimd.cs

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,6 +1699,177 @@ public abstract class PackedSimd
16991699
[Intrinsic]
17001700
public static Vector128<nuint> CompareGreaterThanOrEqual(Vector128<nuint> left, Vector128<nuint> right) => CompareGreaterThanOrEqual(left, right);
17011701

1702+
// Floating-point sign bit operations
1703+
1704+
/// <summary>
1705+
/// f32x4.neg
1706+
/// </summary>
1707+
[Intrinsic]
1708+
public static Vector128<float> Negate(Vector128<float> value) => Negate(value);
1709+
/// <summary>
1710+
/// f64x2.neg
1711+
/// </summary>
1712+
[Intrinsic]
1713+
public static Vector128<double> Negate(Vector128<double> value) => Negate(value);
1714+
1715+
/// <summary>
1716+
/// f32x4.abs
1717+
/// </summary>
1718+
[Intrinsic]
1719+
public static Vector128<float> Abs(Vector128<float> value) => Abs(value);
1720+
/// <summary>
1721+
/// f64x2.abs
1722+
/// </summary>
1723+
[Intrinsic]
1724+
public static Vector128<double> Abs(Vector128<double> value) => Abs(value);
1725+
1726+
// Floating-point min and max
1727+
1728+
/// <summary>
1729+
/// f32x4.min
1730+
/// </summary>
1731+
[Intrinsic]
1732+
public static Vector128<float> Min(Vector128<float> left, Vector128<float> right) => Min(left, right);
1733+
/// <summary>
1734+
/// f64x2.min
1735+
/// </summary>
1736+
[Intrinsic]
1737+
public static Vector128<double> Min(Vector128<double> left, Vector128<double> right) => Min(left, right);
1738+
1739+
/// <summary>
1740+
/// f32x4.max
1741+
/// </summary>
1742+
[Intrinsic]
1743+
public static Vector128<float> Max(Vector128<float> left, Vector128<float> right) => Max(left, right);
1744+
/// <summary>
1745+
/// f64x2.max
1746+
/// </summary>
1747+
[Intrinsic]
1748+
public static Vector128<double> Max(Vector128<double> left, Vector128<double> right) => Max(left, right);
1749+
1750+
/// <summary>
1751+
/// f32x4.pmin
1752+
/// </summary>
1753+
[Intrinsic]
1754+
public static Vector128<float> PseudoMin(Vector128<float> left, Vector128<float> right) => PseudoMin(left, right);
1755+
/// <summary>
1756+
/// f64x2.pmin
1757+
/// </summary>
1758+
[Intrinsic]
1759+
public static Vector128<double> PseudoMin(Vector128<double> left, Vector128<double> right) => PseudoMin(left, right);
1760+
1761+
/// <summary>
1762+
/// f32x4.pmax
1763+
/// </summary>
1764+
[Intrinsic]
1765+
public static Vector128<float> PseudoMax(Vector128<float> left, Vector128<float> right) => PseudoMax(left, right);
1766+
/// <summary>
1767+
/// f64x2.pmax
1768+
/// </summary>
1769+
[Intrinsic]
1770+
public static Vector128<double> PseudoMax(Vector128<double> left, Vector128<double> right) => PseudoMax(left, right);
1771+
1772+
// Floating-point arithmetic
1773+
1774+
/// <summary>
1775+
/// f32x4.add
1776+
/// </summary>
1777+
[Intrinsic]
1778+
public static Vector128<float> Add(Vector128<float> left, Vector128<float> right) => Add(left, right);
1779+
/// <summary>
1780+
/// f64x2.add
1781+
/// </summary>
1782+
[Intrinsic]
1783+
public static Vector128<double> Add(Vector128<double> left, Vector128<double> right) => Add(left, right);
1784+
1785+
/// <summary>
1786+
/// f32x4.sub
1787+
/// </summary>
1788+
[Intrinsic]
1789+
public static Vector128<float> Subtract(Vector128<float> left, Vector128<float> right) => Subtract(left, right);
1790+
/// <summary>
1791+
/// f64x2.sub
1792+
/// </summary>
1793+
[Intrinsic]
1794+
public static Vector128<double> Subtract(Vector128<double> left, Vector128<double> right) => Subtract(left, right);
1795+
1796+
/// <summary>
1797+
/// f32x4.div
1798+
/// </summary>
1799+
[Intrinsic]
1800+
public static Vector128<float> Divide(Vector128<float> left, Vector128<float> right) => Divide(left, right);
1801+
/// <summary>
1802+
/// f64x2.div
1803+
/// </summary>
1804+
[Intrinsic]
1805+
public static Vector128<double> Divide(Vector128<double> left, Vector128<double> right) => Divide(left, right);
1806+
1807+
/// <summary>
1808+
/// f32x4.mul
1809+
/// </summary>
1810+
[Intrinsic]
1811+
public static Vector128<float> Multiply(Vector128<float> left, Vector128<float> right) => Multiply(left, right);
1812+
/// <summary>
1813+
/// f64x2.mul
1814+
/// </summary>
1815+
[Intrinsic]
1816+
public static Vector128<double> Multiply(Vector128<double> left, Vector128<double> right) => Multiply(left, right);
1817+
1818+
/// <summary>
1819+
/// f32x4.sqrt
1820+
/// </summary>
1821+
[Intrinsic]
1822+
public static Vector128<float> Sqrt(Vector128<float> value) => Sqrt(value);
1823+
/// <summary>
1824+
/// f64x2.sqrt
1825+
/// </summary>
1826+
[Intrinsic]
1827+
public static Vector128<double> Sqrt(Vector128<double> value) => Sqrt(value);
1828+
1829+
/// <summary>
1830+
/// f32x4.ceil
1831+
/// </summary>
1832+
[Intrinsic]
1833+
public static Vector128<float> Ceiling(Vector128<float> value) => Ceiling(value);
1834+
/// <summary>
1835+
/// f64x2.ceil
1836+
/// </summary>
1837+
[Intrinsic]
1838+
public static Vector128<double> Ceiling(Vector128<double> value) => Ceiling(value);
1839+
1840+
/// <summary>
1841+
/// f32x4.floor
1842+
/// </summary>
1843+
[Intrinsic]
1844+
public static Vector128<float> Floor(Vector128<float> value) => Floor(value);
1845+
/// <summary>
1846+
/// f64x2.floor
1847+
/// </summary>
1848+
[Intrinsic]
1849+
public static Vector128<double> Floor(Vector128<double> value) => Floor(value);
1850+
1851+
/// <summary>
1852+
/// f32x4.trunc
1853+
/// </summary>
1854+
[Intrinsic]
1855+
public static Vector128<float> Truncate(Vector128<float> value) => Truncate(value);
1856+
/// <summary>
1857+
/// f64x2.trunc
1858+
/// </summary>
1859+
[Intrinsic]
1860+
public static Vector128<double> Truncate(Vector128<double> value) => Truncate(value);
1861+
1862+
/// <summary>
1863+
/// f32x4.nearest
1864+
/// </summary>
1865+
[Intrinsic]
1866+
public static Vector128<float> RoundToNearest(Vector128<float> value) => RoundToNearest(value);
1867+
/// <summary>
1868+
/// f64x2.nearest
1869+
/// </summary>
1870+
[Intrinsic]
1871+
public static Vector128<double> RoundToNearest(Vector128<double> value) => RoundToNearest(value);
1872+
17021873
// Conversions
17031874

17041875
/// <summary>

src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6403,5 +6403,35 @@ public abstract partial class PackedSimd
64036403
public static Vector128<double> CompareGreaterThanOrEqual(Vector128<double> left, Vector128<double> right) { throw null; }
64046404
public static Vector128<nint> CompareGreaterThanOrEqual(Vector128<nint> left, Vector128<nint> right) { throw null; }
64056405
public static Vector128<nuint> CompareGreaterThanOrEqual(Vector128<nuint> left, Vector128<nuint> right) { throw null; }
6406+
public static Vector128<float> Negate(Vector128<float> value) { throw null; }
6407+
public static Vector128<double> Negate(Vector128<double> value) { throw null; }
6408+
public static Vector128<float> Abs(Vector128<float> value) { throw null; }
6409+
public static Vector128<double> Abs(Vector128<double> value) { throw null; }
6410+
public static Vector128<float> Min(Vector128<float> left, Vector128<float> right) { throw null; }
6411+
public static Vector128<double> Min(Vector128<double> left, Vector128<double> right) { throw null; }
6412+
public static Vector128<float> Max(Vector128<float> left, Vector128<float> right) { throw null; }
6413+
public static Vector128<double> Max(Vector128<double> left, Vector128<double> right) { throw null; }
6414+
public static Vector128<float> PseudoMin(Vector128<float> left, Vector128<float> right) { throw null; }
6415+
public static Vector128<double> PseudoMin(Vector128<double> left, Vector128<double> right) { throw null; }
6416+
public static Vector128<float> PseudoMax(Vector128<float> left, Vector128<float> right) { throw null; }
6417+
public static Vector128<double> PseudoMax(Vector128<double> left, Vector128<double> right) { throw null; }
6418+
public static Vector128<float> Add(Vector128<float> left, Vector128<float> right) { throw null; }
6419+
public static Vector128<double> Add(Vector128<double> left, Vector128<double> right) { throw null; }
6420+
public static Vector128<float> Subtract(Vector128<float> left, Vector128<float> right) { throw null; }
6421+
public static Vector128<double> Subtract(Vector128<double> left, Vector128<double> right) { throw null; }
6422+
public static Vector128<float> Divide(Vector128<float> left, Vector128<float> right) { throw null; }
6423+
public static Vector128<double> Divide(Vector128<double> left, Vector128<double> right) { throw null; }
6424+
public static Vector128<float> Multiply(Vector128<float> left, Vector128<float> right) { throw null; }
6425+
public static Vector128<double> Multiply(Vector128<double> left, Vector128<double> right) { throw null; }
6426+
public static Vector128<float> Sqrt(Vector128<float> value) { throw null; }
6427+
public static Vector128<double> Sqrt(Vector128<double> value) { throw null; }
6428+
public static Vector128<float> Ceiling(Vector128<float> value) { throw null; }
6429+
public static Vector128<double> Ceiling(Vector128<double> value) { throw null; }
6430+
public static Vector128<float> Floor(Vector128<float> value) { throw null; }
6431+
public static Vector128<double> Floor(Vector128<double> value) { throw null; }
6432+
public static Vector128<float> Truncate(Vector128<float> value) { throw null; }
6433+
public static Vector128<double> Truncate(Vector128<double> value) { throw null; }
6434+
public static Vector128<float> RoundToNearest(Vector128<float> value) { throw null; }
6435+
public static Vector128<double> RoundToNearest(Vector128<double> value) { throw null; }
64066436
}
64076437
}

src/mono/mono/mini/llvm-intrinsics.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ INTRINS(PEXT_I64, x86_bmi_pext_64, X86)
100100
INTRINS(PDEP_I32, x86_bmi_pdep_32, X86)
101101
INTRINS(PDEP_I64, x86_bmi_pdep_64, X86)
102102

103+
INTRINS_OVR(SIMD_SQRT_R8, sqrt, Generic, sse_r8_t)
104+
INTRINS_OVR(SIMD_SQRT_R4, sqrt, Generic, sse_r4_t)
105+
INTRINS_OVR_TAG(SIMD_FLOOR, floor, Generic, Scalar | V64 | V128 | R4 | R8)
106+
INTRINS_OVR_TAG(SIMD_CEIL, ceil, Generic, Scalar | V64 | V128 | R4 | R8)
107+
INTRINS_OVR_TAG(SIMD_TRUNC, trunc, Generic, Scalar | V64 | V128 | R4 | R8)
108+
INTRINS_OVR_TAG(SIMD_ROUND, round, Generic, Scalar | V64 | V128 | R4 | R8)
109+
INTRINS_OVR_TAG(SIMD_NEAREST, nearbyint, Generic, V64 | V128 | R4 | R8)
110+
103111
#if LLVM_API_VERSION >= 1400
104112
INTRINS_OVR_TAG(ROUNDEVEN, roundeven, Generic, Scalar | V64 | V128 | R4 | R8)
105113
#endif
@@ -124,8 +132,6 @@ INTRINS(SSE_PSRL_Q, x86_sse2_psrl_q, X86)
124132
INTRINS(SSE_PSLL_W, x86_sse2_psll_w, X86)
125133
INTRINS(SSE_PSLL_D, x86_sse2_psll_d, X86)
126134
INTRINS(SSE_PSLL_Q, x86_sse2_psll_q, X86)
127-
INTRINS_OVR(SSE_SQRT_PD, sqrt, Generic, sse_r8_t)
128-
INTRINS_OVR(SSE_SQRT_PS, sqrt, Generic, sse_r4_t)
129135
INTRINS_OVR(SSE_SQRT_SD, sqrt, Generic, LLVMDoubleType ())
130136
INTRINS_OVR(SSE_SQRT_SS, sqrt, Generic, LLVMFloatType ())
131137
INTRINS(SSE_RCP_PS, x86_sse_rcp_ps, X86)
@@ -283,6 +289,10 @@ INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V16, wasm_narrow_signed, Wasm, sse_i1_t, ss
283289
INTRINS_OVR_2_ARG(WASM_NARROW_SIGNED_V8, wasm_narrow_signed, Wasm, sse_i2_t, sse_i4_t)
284290
INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V16, wasm_narrow_unsigned, Wasm, sse_i1_t, sse_i2_t)
285291
INTRINS_OVR_2_ARG(WASM_NARROW_UNSIGNED_V8, wasm_narrow_unsigned, Wasm, sse_i2_t, sse_i4_t)
292+
INTRINS_OVR_TAG(WASM_PMAX, wasm_pmax, Wasm, V128 | R4 | R8)
293+
INTRINS_OVR_TAG(WASM_PMIN, wasm_pmin, Wasm, V128 | R4 | R8)
294+
INTRINS_OVR(WASM_PMAX_V4, fabs, Generic, sse_r4_t)
295+
INTRINS_OVR(WASM_PMAX_V2, fabs, Generic, sse_r8_t)
286296
INTRINS(WASM_Q15MULR_SAT_SIGNED, wasm_q15mulr_sat_signed, Wasm)
287297
INTRINS(WASM_SHUFFLE, wasm_shuffle, Wasm)
288298
INTRINS_OVR(WASM_SUB_SAT_SIGNED_V16, wasm_sub_sat_signed, Wasm, sse_i1_t)
@@ -436,13 +446,9 @@ INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRECPS, aarch64_neon_frecps, Arm64, Scalar | V6
436446
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_RBIT, aarch64_neon_rbit, Arm64, V64 | V128 | I1)
437447
#endif
438448

439-
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTA, round, Generic, Scalar | V64 | V128 | R4 | R8)
440449
#if LLVM_API_VERSION < 1400
441450
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTN, aarch64_neon_frintn, Arm64, Scalar | V64 | V128 | R4 | R8)
442451
#endif
443-
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTM, floor, Generic, Scalar | V64 | V128 | R4 | R8)
444-
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTP, ceil, Generic, Scalar | V64 | V128 | R4 | R8)
445-
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_FRINTZ, trunc, Generic, Scalar | V64 | V128 | R4 | R8)
446452

447453
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_SUQADD, aarch64_neon_suqadd, Arm64, Scalar | V64 | V128 | I1 | I2 | I4 | I8)
448454
INTRINS_OVR_TAG(AARCH64_ADV_SIMD_USQADD, aarch64_neon_usqadd, Arm64, Scalar | V64 | V128 | I1 | I2 | I4 | I8)

0 commit comments

Comments
 (0)