IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
Vector128Util.cs
Go to the documentation of this file.
1#if NETCOREAPP3_0_OR_GREATER
2
3using System;
5using System.Runtime.InteropServices;
6using System.Runtime.Intrinsics;
7
9{
10
14 static class Vector128Util
15 {
16
23 [MethodImpl(MethodImplOptions.AggressiveInlining)]
24 public static void CopyTo<T>(this Vector128<T> vector, Span<T> destination) where T : struct
25 {
26#if NET8_0_OR_GREATER
27 Vector128.CopyTo(vector, destination);
28#else
29 if (destination.Length < Vector128<T>.Count)
30 throw new ArgumentException(null, nameof(destination));
31
32 Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(destination)), vector);
33#endif
34 }
35
42 [MethodImpl(MethodImplOptions.AggressiveInlining)]
43 public static Vector128<T> Create<T>(ReadOnlySpan<T> values) where T : struct
44 {
45#if NET8_0_OR_GREATER
46 return Vector128.Create(values);
47#else
48 if (values.Length < Vector128<T>.Count)
49 throw new ArgumentOutOfRangeException(nameof(values));
50
51 return Unsafe.ReadUnaligned<Vector128<T>>(ref Unsafe.As<T, byte>(ref MemoryMarshal.GetReference(values)));
52#endif
53 }
54
61 [MethodImpl(MethodImplOptions.AggressiveInlining)]
62 public static (Vector128<T> V1, Vector128<T> V2) Load2xUnsafe<T>(ref readonly T source) where T : struct
63 {
64 return (
65 LoadUnsafe(in source, 0 * (nuint)Vector128<T>.Count),
66 LoadUnsafe(in source, 1 * (nuint)Vector128<T>.Count)
67 );
68 }
69
76 [MethodImpl(MethodImplOptions.AggressiveInlining)]
77 public static (Vector128<T> V1, Vector128<T> V2, Vector128<T> V3) Load3xUnsafe<T>(ref readonly T source) where T : struct
78 {
79 return (
80 LoadUnsafe(in source, 0 * (nuint)Vector128<T>.Count),
81 LoadUnsafe(in source, 1 * (nuint)Vector128<T>.Count),
82 LoadUnsafe(in source, 2 * (nuint)Vector128<T>.Count)
83 );
84 }
85
92 [MethodImpl(MethodImplOptions.AggressiveInlining)]
93 public static (Vector128<T> V1, Vector128<T> V2, Vector128<T> V3, Vector128<T> V4) Load4xUnsafe<T>(ref readonly T source) where T : struct
94 {
95 return (
96 LoadUnsafe(in source, 0 * (nuint)Vector128<T>.Count),
97 LoadUnsafe(in source, 1 * (nuint)Vector128<T>.Count),
98 LoadUnsafe(in source, 2 * (nuint)Vector128<T>.Count),
99 LoadUnsafe(in source, 3 * (nuint)Vector128<T>.Count)
100 );
101 }
102
109 [MethodImpl(MethodImplOptions.AggressiveInlining)]
110 public static Vector128<T> LoadUnsafe<T>(ref readonly T source) where T : struct
111 {
112#if NET8_0_OR_GREATER
113 return Vector128.LoadUnsafe(in source);
114#else
115 // Use with caution.
116 // Supports blittable primitives only.
117 ref byte address = ref Unsafe.As<T, byte>(ref Unsafe.AsRef(in source));
118 return Unsafe.ReadUnaligned<Vector128<T>>(ref address);
119#endif
120 }
121
129 [MethodImpl(MethodImplOptions.AggressiveInlining)]
130 public static Vector128<T> LoadUnsafe<T>(ref readonly T source, nuint elementOffset) where T : struct
131 {
132#if NET8_0_OR_GREATER
133 return Vector128.LoadUnsafe(in source, elementOffset);
134#else
135 // Use with caution.
136 // Supports blittable primitives only.
137 ref byte address = ref Unsafe.As<T, byte>(ref Unsafe.Add(ref Unsafe.AsRef(in source), (nint)elementOffset));
138 return Unsafe.ReadUnaligned<Vector128<T>>(ref address);
139#endif
140 }
141
148 [MethodImpl(MethodImplOptions.AggressiveInlining)]
149 public static void StoreUnsafe<T>(this Vector128<T> source, ref T destination) where T : struct
150 {
151#if NET8_0_OR_GREATER
152 Vector128.StoreUnsafe(source, ref destination);
153#else
154 // Use with caution.
155 // Supports blittable primitives only.
156 ref byte address = ref Unsafe.As<T, byte>(ref destination);
157 Unsafe.WriteUnaligned(ref address, source);
158#endif
159 }
160
168 [MethodImpl(MethodImplOptions.AggressiveInlining)]
169 public static void StoreUnsafe<T>(this Vector128<T> source, ref T destination, nuint elementOffset) where T : struct
170 {
171#if NET8_0_OR_GREATER
172 Vector128.StoreUnsafe(source, ref destination, elementOffset);
173#else
174 // Use with caution.
175 // Supports blittable primitives only.
176 destination = ref Unsafe.Add(ref destination, (nint)elementOffset);
177 Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref destination), source);
178#endif
179 }
180 }
181}
182
183#endif