|
@@ -2,7 +2,9 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
+using System.Numerics;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
+using System.Runtime.Intrinsics;
|
|
|
using System.Text;
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
@@ -19,14 +21,32 @@ namespace SIMDFxpConvert
|
|
|
uint onecount = (uint)(512 / (Unsafe.SizeOf<double>() * 8));
|
|
|
uint c = count / onecount;
|
|
|
ref var source = ref Unsafe.As<double, System.Runtime.Intrinsics.Vector512<double>>(ref value);
|
|
|
- ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
|
|
|
+ Vector512<double> max = Vector512<double>.One * dxpinfo.Max;
|
|
|
+ Vector512<double> min = Vector512<double>.One * dxpinfo.Min;
|
|
|
+ ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
|
|
|
for (int i = 0; i < c; i++)
|
|
|
{
|
|
|
- var temp = Unsafe.Add(ref source, i) * pow;
|
|
|
- for (int j = 0; j < onecount; j++)
|
|
|
+ var temp = Unsafe.Add(ref source, i);
|
|
|
+ temp = Vector512.Max(min, temp);
|
|
|
+ temp = Vector512.Min(max, temp);
|
|
|
+ temp *= pow;
|
|
|
+
|
|
|
+ if (dxpinfo.isSigned)
|
|
|
+ {
|
|
|
+ for (int j = 0; j < onecount; j++)
|
|
|
+ {
|
|
|
+ fxpptr[i * onecount + j] = dxpinfo.wordLength > 32 ? (((ulong)(long)temp[j]) << (64 - dxpinfo.wordLength)) : ((ulong)(long)temp[j]);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
- fxpptr[i * onecount + j] = (ulong)temp[j];
|
|
|
+ for (int j = 0; j < onecount; j++)
|
|
|
+ {
|
|
|
+ fxpptr[i * onecount + j] = dxpinfo.wordLength > 32 ? (((ulong)temp[j]) << (64 - dxpinfo.wordLength)) : ((ulong)temp[j]);
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
uint c1 = count % onecount;
|
|
|
if (c1 != 0)
|
|
@@ -34,10 +54,19 @@ namespace SIMDFxpConvert
|
|
|
uint start = c * onecount;
|
|
|
for (uint i = 0; i < c1; i++)
|
|
|
{
|
|
|
- ref double temp = ref Unsafe.Add(ref value, start + i);
|
|
|
+ double temp = Math.Clamp(Unsafe.Add(ref value, start + i),dxpinfo.Min,dxpinfo.Max);
|
|
|
+
|
|
|
+ if (dxpinfo.isSigned)
|
|
|
+ {
|
|
|
+ ref long templ = ref Unsafe.As<ulong, long>(ref Unsafe.Add(ref fxp, start + i));
|
|
|
+ templ = dxpinfo.wordLength > 32 ? (((long)(temp * pow)) << (64 - dxpinfo.wordLength)) : ((long)(temp * pow));
|
|
|
|
|
|
- ref ulong tempu = ref Unsafe.Add(ref fxp, start + i);
|
|
|
- tempu = (ulong)(temp * pow);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ref ulong tempu = ref Unsafe.Add(ref fxp, start + i);
|
|
|
+ tempu = dxpinfo.wordLength > 32 ? (((ulong)(temp * pow)) << (64 - dxpinfo.wordLength)) : ((ulong)(temp * pow));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -49,13 +78,29 @@ namespace SIMDFxpConvert
|
|
|
uint onecount = (uint)(512 / (Unsafe.SizeOf<float>() * 8));
|
|
|
uint c = count / onecount;
|
|
|
ref var source = ref Unsafe.As<float, System.Runtime.Intrinsics.Vector512<float>>(ref value);
|
|
|
- ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
|
|
|
+ ulong* fxpptr = (ulong*)Unsafe.AsPointer(ref fxp);
|
|
|
+ Vector512<float> max = Vector512<float>.One * (float)dxpinfo.Max;
|
|
|
+ Vector512<float> min = Vector512<float>.One * (float)dxpinfo.Min;
|
|
|
for (int i = 0; i < c; i++)
|
|
|
{
|
|
|
- var temp = Unsafe.Add(ref source, i) * pow;
|
|
|
- for (int j = 0; j < onecount; j++)
|
|
|
+ var temp = Unsafe.Add(ref source, i);
|
|
|
+ temp = Vector512.Max(min, temp);
|
|
|
+ temp = Vector512.Min(max, temp);
|
|
|
+ temp *= pow;
|
|
|
+ if (dxpinfo.isSigned)
|
|
|
{
|
|
|
- fxpptr[i * onecount + j] = (ulong)temp[j];
|
|
|
+ for (int j = 0; j < onecount; j++)
|
|
|
+ {
|
|
|
+ fxpptr[i * onecount + j] = dxpinfo.wordLength>32?(((ulong)(long)temp[j])<<(64-dxpinfo.wordLength)): ((ulong)(long)temp[j]) ;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ for (int j = 0; j < onecount; j++)
|
|
|
+ {
|
|
|
+ fxpptr[i * onecount + j] =dxpinfo.wordLength>32?(((ulong)temp[j])<<(64-dxpinfo.wordLength)) : ((ulong)temp[j]) ;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
uint c1 = count % onecount;
|
|
@@ -64,10 +109,18 @@ namespace SIMDFxpConvert
|
|
|
uint start = c * onecount;
|
|
|
for (uint i = 0; i < c1; i++)
|
|
|
{
|
|
|
- ref float temp = ref Unsafe.Add(ref value, start + i);
|
|
|
+ float temp =Math.Clamp(Unsafe.Add(ref value, start + i),(float)dxpinfo.Min,(float)dxpinfo.Max);
|
|
|
+ if (dxpinfo.isSigned)
|
|
|
+ {
|
|
|
+ ref long templ = ref Unsafe.As<ulong, long>(ref Unsafe.Add(ref fxp, start + i));
|
|
|
+ templ = dxpinfo.wordLength>32?(((long)(temp * pow))<<(64-dxpinfo.wordLength)) : ((long)(temp * pow)) ;
|
|
|
|
|
|
- ref ulong tempu = ref Unsafe.Add(ref fxp, start + i);
|
|
|
- tempu = (ulong)(temp * pow);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ref ulong tempu = ref Unsafe.Add(ref fxp, start + i);
|
|
|
+ tempu = dxpinfo.wordLength > 32 ? (((ulong)(temp * pow)) << (64 - dxpinfo.wordLength)) : ((ulong)(temp * pow)) ;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -84,7 +137,12 @@ namespace SIMDFxpConvert
|
|
|
{
|
|
|
ref double resultref = ref Unsafe.Add(ref value, i);
|
|
|
ref ulong tempfxpref = ref Unsafe.Add(ref fxp, i);
|
|
|
- ulong tempdata = tempfxpref & mask;
|
|
|
+ ulong tempdata = 0;
|
|
|
+ if (dxpinfo.wordLength > 32)
|
|
|
+ {
|
|
|
+ tempdata = (tempfxpref >> (64 - dxpinfo.wordLength)) & mask;
|
|
|
+ }
|
|
|
+ else tempdata = tempfxpref & mask;
|
|
|
if ((tempdata & signedmask) != 0)
|
|
|
{
|
|
|
long signeddata = (long)(tempdata ^ mask);
|
|
@@ -100,7 +158,7 @@ namespace SIMDFxpConvert
|
|
|
{
|
|
|
ref double resultref = ref Unsafe.Add(ref value, i);
|
|
|
ref ulong tempfxpref = ref Unsafe.Add(ref fxp, i);
|
|
|
- ulong tempdata = tempfxpref & mask;
|
|
|
+ ulong tempdata = (dxpinfo.wordLength > 32 ? (tempfxpref >> (64 - dxpinfo.wordLength)) : tempfxpref) & mask;
|
|
|
resultref = delta * tempdata;
|
|
|
}
|
|
|
}
|
|
@@ -118,7 +176,12 @@ namespace SIMDFxpConvert
|
|
|
{
|
|
|
ref float resultref = ref Unsafe.Add(ref value, i);
|
|
|
ref ulong tempfxpref = ref Unsafe.Add(ref fxp, i);
|
|
|
- ulong tempdata = tempfxpref & mask;
|
|
|
+ ulong tempdata = 0;
|
|
|
+ if (dxpinfo.wordLength>32)
|
|
|
+ {
|
|
|
+ tempdata = (tempfxpref>>(64-dxpinfo.wordLength)) & mask;
|
|
|
+ }
|
|
|
+ else tempdata = tempfxpref & mask;
|
|
|
if ((tempdata & signedmask) != 0)
|
|
|
{
|
|
|
long signeddata = (long)(tempdata ^ mask);
|
|
@@ -134,7 +197,7 @@ namespace SIMDFxpConvert
|
|
|
{
|
|
|
ref float resultref = ref Unsafe.Add(ref value, i);
|
|
|
ref ulong tempfxpref = ref Unsafe.Add(ref fxp, i);
|
|
|
- ulong tempdata = tempfxpref & mask;
|
|
|
+ ulong tempdata = (dxpinfo.wordLength>32?(tempfxpref>>(64-dxpinfo.wordLength)): tempfxpref) & mask;
|
|
|
resultref = delta * tempdata;
|
|
|
}
|
|
|
}
|