private static bool ProblemWithLoadHigh_Sse() { var data = stackalloc float[2]; data[0] = 1; data[1] = 2; JitUse(data); Vector128 <float> a = Vector128 <float> .Zero; Vector128 <float> b = Sse.LoadHigh(a, data); Vector128 <float> c = Sse.LoadHigh(a, data + 1); // Make sure we take into account the address operand. if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) { return(true); } // Make sure we take the heap state into account. b = Sse.LoadHigh(a, data); data[0] = 3; c = Sse.LoadHigh(a, data); if (b.AsInt64().GetElement(1) == c.AsInt64().GetElement(1)) { return(true); } return(false); }
private static bool ProblemWithLoadLow_Sse2() { var data = stackalloc double[2]; data[0] = 1; data[1] = 2; JitUse(data); Vector128 <double> a = Vector128 <double> .Zero; Vector128 <double> b = Sse2.LoadLow(a, data); Vector128 <double> c = Sse2.LoadLow(a, data + 1); // Make sure we take into account the address operand. if (b.AsInt64().GetElement(0) == c.AsInt64().GetElement(0)) { return(true); } // Make sure we take the heap state into account. b = Sse2.LoadLow(a, data); data[0] = 3; c = Sse2.LoadLow(a, data); if (b.AsInt64().GetElement(0) == c.AsInt64().GetElement(0)) { return(true); } return(false); }
private static void HorizontalUnfilter(Span <byte> prev, Span <byte> input, Span <byte> dst, int width) { #if SUPPORTS_RUNTIME_INTRINSICS if (Sse2.IsSupported) { dst[0] = (byte)(input[0] + (prev.IsEmpty ? 0 : prev[0])); if (width <= 1) { return; } nint i; Vector128 <int> last = Vector128 <int> .Zero.WithElement(0, dst[0]); ref byte srcRef = ref MemoryMarshal.GetReference(input); for (i = 1; i + 8 <= width; i += 8) { var a0 = Vector128.Create(Unsafe.As <byte, long>(ref Unsafe.Add(ref srcRef, i)), 0); Vector128 <byte> a1 = Sse2.Add(a0.AsByte(), last.AsByte()); Vector128 <byte> a2 = Sse2.ShiftLeftLogical128BitLane(a1, 1); Vector128 <byte> a3 = Sse2.Add(a1, a2); Vector128 <byte> a4 = Sse2.ShiftLeftLogical128BitLane(a3, 2); Vector128 <byte> a5 = Sse2.Add(a3, a4); Vector128 <byte> a6 = Sse2.ShiftLeftLogical128BitLane(a5, 4); Vector128 <byte> a7 = Sse2.Add(a5, a6); ref byte outputRef = ref Unsafe.Add(ref MemoryMarshal.GetReference(dst), i); Unsafe.As <byte, Vector64 <byte> >(ref outputRef) = a7.GetLower(); last = Sse2.ShiftRightLogical(a7.AsInt64(), 56).AsInt32(); }
public static Vector128 <T> Inc128Le <T>(this Vector128 <T> nonce) where T : struct { Vector128 <long> v = nonce.AsInt64(); Vector128 <long> t = Sse41.CompareEqual(v, MinusOne128Le); v = Sse2.Subtract(v, MinusOne128Le); t = Sse2.ShiftLeftLogical128BitLane(t, 8); return(Sse2.Subtract(v, t).As <long, T>()); }
internal static unsafe long Extract64(Vector128 <sbyte> value) { if (Sse41.X64.IsSupported) { return(Sse41.X64.Extract(value.AsInt64(), 0)); //会在JIT时进行静态判断 } var v = value.AsInt32(); return((long)((uint)Sse41.Extract(v, 0) | ((ulong)Sse41.Extract(v, 1) << 32))); }
public static Vector128 <T> Vector128Add <T>(Vector128 <T> left, Vector128 <T> right) where T : struct { if (typeof(T) == typeof(byte)) { return(Sse2.Add(left.AsByte(), right.AsByte()).As <byte, T>()); } else if (typeof(T) == typeof(sbyte)) { return(Sse2.Add(left.AsSByte(), right.AsSByte()).As <sbyte, T>()); } else if (typeof(T) == typeof(short)) { return(Sse2.Add(left.AsInt16(), right.AsInt16()).As <short, T>()); } else if (typeof(T) == typeof(ushort)) { return(Sse2.Add(left.AsUInt16(), right.AsUInt16()).As <ushort, T>()); } else if (typeof(T) == typeof(int)) { return(Sse2.Add(left.AsInt32(), right.AsInt32()).As <int, T>()); } else if (typeof(T) == typeof(uint)) { return(Sse2.Add(left.AsUInt32(), right.AsUInt32()).As <uint, T>()); } else if (typeof(T) == typeof(long)) { return(Sse2.Add(left.AsInt64(), right.AsInt64()).As <long, T>()); } else if (typeof(T) == typeof(ulong)) { return(Sse2.Add(left.AsUInt64(), right.AsUInt64()).As <ulong, T>()); } else if (typeof(T) == typeof(float)) { return(Sse.Add(left.AsSingle(), right.AsSingle()).As <float, T>()); } else if (typeof(T) == typeof(double)) { return(Sse2.Add(left.AsDouble(), right.AsDouble()).As <double, T>()); } else { throw new NotSupportedException(); } }
static unsafe Vector128 <long> AdvSimd_Arm64_CompareEqual_Vector128_Long_AsVariableLoop(Vector128 <long> left) { Vector128 <long> result = default; Vector128 <long> asVar = Vector128.Create((long)0); Vector128 <nint> asVar2 = Vector128.Create((nint)0); Vector128 <long> asVar3 = asVar2.AsInt64(); for (var i = 0; i < 4; i++) { result = AdvSimd.Arm64.CompareEqual(left, asVar); for (var j = 0; j < 4; j++) { result = AdvSimd.Arm64.CompareEqual(left, asVar3); } } return(result); }