Beispiel #1
0
        public static uint8 lzcnt(uint8 x)
        {
            if (Avx2.IsAvx2Supported)
            {
                v256 ymm0, ymm1, ymm2, ymm3, ymm4;

                v256 ZERO = default(v256);
                v256 MASK = new v256(0x0101_0101_0202_0304L, 0L, 0x0101_0101_0202_0304L, 0L);

                ymm2 = Avx2.mm256_shuffle_epi8(MASK, x);
                ymm3 = Avx2.mm256_srli_epi16(x, 4);
                ymm3 = Avx2.mm256_and_si256(ymm3, new v256(0x0F0F_0F0F));
                ymm4 = Avx2.mm256_cmpeq_epi8(ymm3, ZERO);
                ymm2 = Avx2.mm256_and_si256(ymm2, ymm4);
                ymm1 = Avx2.mm256_shuffle_epi8(MASK, ymm3);
                ymm1 = Avx2.mm256_add_epi8(ymm2, ymm1);
                ymm2 = Avx2.mm256_cmpeq_epi8(x, ZERO);
                ymm2 = Avx2.mm256_srli_epi16(ymm2, 8);
                ymm2 = Avx2.mm256_and_si256(ymm1, ymm2);
                ymm1 = Avx2.mm256_srli_epi16(ymm1, 8);
                ymm1 = Avx2.mm256_add_epi8(ymm1, ymm2);
                ymm0 = Avx2.mm256_cmpeq_epi16(x, ZERO);
                ymm0 = Avx2.mm256_srli_epi32(ymm0, 16);
                ymm0 = Avx2.mm256_and_si256(ymm1, ymm0);
                ymm1 = Avx2.mm256_srli_epi32(ymm1, 16);
                ymm0 = Avx2.mm256_add_epi32(ymm1, ymm0);

                return(ymm0);
            }
            else
            {
                return(new uint8((uint4)math.lzcnt(x.v4_0), (uint4)math.lzcnt(x.v4_4)));
            }
        }
Beispiel #2
0
        public static uint8 bitmask32(uint8 numBits, uint8 index = default(uint8))
        {
            Assert.IsBetween(index.x0, 0u, 32u);
            Assert.IsBetween(index.x1, 0u, 32u);
            Assert.IsBetween(index.x2, 0u, 32u);
            Assert.IsBetween(index.x3, 0u, 32u);
            Assert.IsBetween(index.x4, 0u, 32u);
            Assert.IsBetween(index.x5, 0u, 32u);
            Assert.IsBetween(index.x6, 0u, 32u);
            Assert.IsBetween(index.x7, 0u, 32u);
            Assert.IsBetween(numBits.x0, 0u, 32u - index.x0);
            Assert.IsBetween(numBits.x1, 0u, 32u - index.x1);
            Assert.IsBetween(numBits.x2, 0u, 32u - index.x2);
            Assert.IsBetween(numBits.x3, 0u, 32u - index.x3);
            Assert.IsBetween(numBits.x4, 0u, 32u - index.x4);
            Assert.IsBetween(numBits.x5, 0u, 32u - index.x5);
            Assert.IsBetween(numBits.x6, 0u, 32u - index.x6);
            Assert.IsBetween(numBits.x7, 0u, 32u - index.x7);


            if (Avx2.IsAvx2Supported)
            {
                // mask
                index = shl(uint.MaxValue, index);

                v256 isMaxBitsMask = Avx2.mm256_cmpeq_epi32(numBits, new v256(32));

                return(isMaxBitsMask | andnot(index, shl(index, numBits)));
            }
            else
            {
                return(new uint8(bitmask32(numBits.v4_0, index.v4_0), bitmask32(numBits.v4_4, index.v4_4)));
            }
        }
Beispiel #3
0
        public static int indexof(uint8 v, uint x)
        {
            if (Avx2.IsAvx2Supported)
            {
                return(math.tzcnt(Avx.mm256_movemask_ps(Avx2.mm256_cmpeq_epi32(v, new uint8(x)))));
            }
            else if (Sse2.IsSse2Supported)
            {
                v128 broadcast = new v128(x);

                return(math.tzcnt(Sse.movemask_ps(Sse2.cmpeq_epi32(*(v128 *)&v._v4_0, broadcast)) |
                                  (Sse.movemask_ps(Sse2.cmpeq_epi32(*(v128 *)&v._v4_4, broadcast)) << 4)));
            }
            else
            {
                for (int i = 0; i < 8; i++)
                {
                    if (v[i] == x)
                    {
                        return(i);
                    }
                    else
                    {
                        continue;
                    }
                }

                return(32);
            }
        }
        public static uint8 lcm(int8 x, int8 y)
        {
            uint8 absX = (uint8)abs(x);
            uint8 absY = (uint8)abs(y);

            return((absX / gcd(absX, absY)) * absY);
        }
Beispiel #5
0
        public uint8 NextUInt8(uint8 min, uint8 max)
        {
            Assert.IsNotSmaller(max.x0, min.x0);
            Assert.IsNotSmaller(max.x1, min.x1);
            Assert.IsNotSmaller(max.x2, min.x2);
            Assert.IsNotSmaller(max.x3, min.x3);
            Assert.IsNotSmaller(max.x4, min.x4);
            Assert.IsNotSmaller(max.x5, min.x5);
            Assert.IsNotSmaller(max.x6, min.x6);
            Assert.IsNotSmaller(max.x7, min.x7);

            if (Avx2.IsAvx2Supported)
            {
                max -= min;

                v256 hiProd_lo = Avx2.mm256_mul_epu32(new v256(NextState(), 0, NextState(), 0, NextState(), 0, NextState(), 0), (ulong4)max.v4_0);
                v256 hiProd_hi = Avx2.mm256_mul_epu32(new v256(NextState(), 0, NextState(), 0, NextState(), 0, NextState(), 0), (ulong4)max.v4_4);

                hiProd_lo = Avx2.mm256_permutevar8x32_epi32(hiProd_lo, Avx.mm256_castsi128_si256(new v128(1, 3, 5, 7)));
                hiProd_hi = Avx2.mm256_permutevar8x32_epi32(hiProd_hi, Avx.mm256_castsi128_si256(new v128(1, 3, 5, 7)));

                return(min + Avx.mm256_set_m128i(Avx.mm256_castsi256_si128(hiProd_hi), Avx.mm256_castsi256_si128(hiProd_lo)));
            }
            else
            {
                Unity.Mathematics.Random rng = this;

                return(new uint8(rng.NextUInt4(min.v4_0, max.v4_0), rng.NextUInt4(min.v4_4, max.v4_4)));
            }
        }
Beispiel #6
0
        public static bool16 isdivisible(ushort16 dividend, ushort16 divisor)
        {
            Assert.AreNotEqual(0, divisor.x0);
            Assert.AreNotEqual(0, divisor.x1);
            Assert.AreNotEqual(0, divisor.x2);
            Assert.AreNotEqual(0, divisor.x3);
            Assert.AreNotEqual(0, divisor.x4);
            Assert.AreNotEqual(0, divisor.x5);
            Assert.AreNotEqual(0, divisor.x6);
            Assert.AreNotEqual(0, divisor.x7);
            Assert.AreNotEqual(0, divisor.x8);
            Assert.AreNotEqual(0, divisor.x9);
            Assert.AreNotEqual(0, divisor.x10);
            Assert.AreNotEqual(0, divisor.x11);
            Assert.AreNotEqual(0, divisor.x12);
            Assert.AreNotEqual(0, divisor.x13);
            Assert.AreNotEqual(0, divisor.x14);
            Assert.AreNotEqual(0, divisor.x15);

            if (Constant.IsConstantExpression(divisor))
            {
                uint8 compile_lo = (new uint8(uint.MaxValue) / divisor.v8_0) + 1;
                uint8 compile_hi = (new uint8(uint.MaxValue) / divisor.v8_8) + 1;

                return(new bool16(dividend.v8_0 * compile_lo <= compile_lo - 1,
                                  dividend.v8_8 * compile_lo <= compile_lo - 1));
            }
            else
            {
                return(dividend % divisor == 0);
            }
        }
Beispiel #7
0
        public static uint8 tzcnt(uint8 x)
        {
            if (Avx2.IsAvx2Supported)
            {
                v256 ymm0, ymm1, ymm2;

                v256 ZERO     = default;
                v256 ALL_ONES = Avx2.mm256_cmpeq_epi32(ZERO, ZERO);
                v256 MASK     = new v256(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
                                         0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);

                ymm1 = Avx2.mm256_add_epi32(x, ALL_ONES);
                ymm0 = Avx2.mm256_andnot_si256(x, ymm1);
                ymm2 = Avx2.mm256_and_si256(ymm0, new v256(0x0F0F_0F0F));
                ymm2 = Avx2.mm256_shuffle_epi8(MASK, ymm2);
                ymm0 = Avx2.mm256_srli_epi16(ymm0, 4);
                ymm0 = Avx2.mm256_and_si256(ymm0, ymm1);
                ymm0 = Avx2.mm256_shuffle_epi8(MASK, ymm0);
                ymm0 = Avx2.mm256_add_epi8(ymm0, ymm2);
                ymm2 = Avx2.mm256_unpackhi_epi32(ymm0, ZERO);
                ymm2 = Avx2.mm256_sad_epu8(ymm2, ZERO);
                ymm0 = Avx2.mm256_unpacklo_epi32(ymm0, ZERO);
                ymm0 = Avx2.mm256_sad_epu8(ymm0, ZERO);
                ymm0 = Avx2.mm256_packus_epi16(ymm0, ymm2);

                return(ymm0);
            }
            else
            {
                return(new uint8((uint4)math.tzcnt(x.v4_0), (uint4)math.tzcnt(x.v4_4)));
            }
        }
Beispiel #8
0
        internal static float8 UInt8ToFloat8(uint8 x)
        {
            int8 signed   = (int8)x & 0x7FFF_FFFF;
            int8 signMask = ((int8)x >> 31) & 0x4F00_0000;

            return((float8)signed + (v256)signMask);
        }
Beispiel #9
0
        public static uint8 reversebits(uint8 x)
        {
            x = ((x >> 1) & 0x5555_5555u) | ((x & 0x5555_5555u) << 1);
            x = ((x >> 2) & 0x3333_3333u) | ((x & 0x3333_3333u) << 2);
            x = ((x >> 4) & 0x0F0F_0F0Fu) | ((x & 0x0F0F_0F0Fu) << 4);
            x = ((x >> 8) & 0x00FF_00FFu) | ((x & 0x00FF_00FFu) << 8);

            return((x >> 16) | (x << 16));
        }
Beispiel #10
0
        public static uint8 floorpow2(uint8 x)
        {
            x |= x >> 1;
            x |= x >> 2;
            x |= x >> 4;
            x |= x >> 8;
            x |= x >> 16;

            return(x - (x >> 1));
        }
Beispiel #11
0
 public static float8 asfloat(uint8 x)
 {
     if (Avx.IsAvxSupported)
     {
         return((v256)x);
     }
     else
     {
         return(*(float8 *)&x);
     }
 }
Beispiel #12
0
 public DebuggerProxy(uint8 v)
 {
     x0 = v.x0;
     x1 = v.x1;
     x2 = v.x2;
     x3 = v.x3;
     x4 = v.x4;
     x5 = v.x5;
     x6 = v.x6;
     x7 = v.x7;
 }
Beispiel #13
0
 public static uint8 max(uint8 a, uint8 b)
 {
     if (Avx2.IsAvx2Supported)
     {
         return(Avx2.mm256_max_epu32(a, b));
     }
     else
     {
         return(new uint8(math.max(a.v4_0, b.v4_0), math.max(a.v4_4, b.v4_4)));
     }
 }
Beispiel #14
0
        public static uint8 ceilpow2(uint8 x)
        {
            x -= 1;
            x |= x >> 1;
            x |= x >> 2;
            x |= x >> 4;
            x |= x >> 8;
            x |= x >> 16;

            return(x + 1);
        }
Beispiel #15
0
 public static uint8 subadd(uint8 a, uint8 b)
 {
     if (Avx2.IsAvx2Supported)
     {
         return(a + Avx2.mm256_sign_epi32(b, new uint8(uint.MaxValue, 1, uint.MaxValue, 1, uint.MaxValue, 1, uint.MaxValue, 1)));
     }
     else
     {
         return(new uint8(subadd(a.v4_0, b.v4_0), subadd(a.v4_4, b.v4_4)));
     }
 }
Beispiel #16
0
 public static bool8 ispow2(uint8 x)
 {
     if (Avx2.IsAvx2Supported)
     {
         return((v128)(new byte8(1) & (byte8)(uint8)Avx2.mm256_and_si256(Operator.greater_mask_uint(x, default(v256)),
                                                                         Avx2.mm256_cmpeq_epi32(default(v256), x & (x - 1)))));
     }
     else
     {
         return(new bool8(math.ispow2(x.v4_0), math.ispow2(x.v4_4)));
     }
 }
        public static bool8 toboolsafe(uint8 x)
        {
            if (Sse2.IsSse2Supported)
            {
                return((v128)(byte8)clamp(x, 0, 1));
            }
            else
            {
                byte8 temp = (byte8)clamp(x, 0, 1);

                return(*(bool8 *)&temp);
            }
        }
Beispiel #18
0
        internal static v256 greater_mask_uint(uint8 left, uint8 right)
        {
            if (Avx2.IsAvx2Supported)
            {
                uint8 mask = 1u << 31;

                return(Avx2.mm256_cmpgt_epi32(Avx2.mm256_xor_si256(left, mask),
                                              Avx2.mm256_xor_si256(right, mask)));
            }
            else
            {
                throw new CPUFeatureCheckException();
            }
        }
Beispiel #19
0
        public static uint8 gcd(uint8 x, uint8 y)
        {
            if (Avx2.IsAvx2Supported)
            {
                v256 ZERO = default(v256);

                v256 result             = ZERO;
                v256 result_if_zero_any = ZERO;

                v256 x_is_zero = Avx2.mm256_cmpeq_epi32(x, ZERO);
                v256 y_is_zero = Avx2.mm256_cmpeq_epi32(y, ZERO);
                v256 any_zero  = Avx2.mm256_or_si256(x_is_zero, y_is_zero);

                result_if_zero_any = Avx2.mm256_blendv_epi8(result_if_zero_any, y, x_is_zero);
                result_if_zero_any = Avx2.mm256_blendv_epi8(result_if_zero_any, x, y_is_zero);

                v256 doneMask = any_zero;

                v256 shift = tzcnt(x | y);

                x = Avx2.mm256_srlv_epi32(x, tzcnt(x));

                do
                {
                    y = Avx2.mm256_srlv_epi32(y, tzcnt(y));

                    v256 tempX = x;

                    x = Avx2.mm256_min_epu32(x, y);
                    y = Avx2.mm256_max_epu32(y, tempX);

                    y -= x;

                    v256 loopCheck = Avx2.mm256_andnot_si256(doneMask, Avx2.mm256_cmpeq_epi32(y, ZERO));
                    result   = Avx2.mm256_blendv_epi8(result, x, loopCheck);
                    doneMask = Avx2.mm256_or_si256(doneMask, loopCheck);
                } while (bitmask32(8 * sizeof(uint)) != Avx2.mm256_movemask_epi8(doneMask));

                result = Avx2.mm256_sllv_epi32(result, shift);

                result = Avx2.mm256_blendv_epi8(result, result_if_zero_any, any_zero);

                return(result);
            }
            else
            {
                return(new uint8(gcd(x.v4_0, y.v4_0), gcd(x.v4_4, y.v4_4)));
            }
        }
Beispiel #20
0
        public static int8 compareto(uint8 x, uint8 y)
        {
            if (Avx2.IsAvx2Supported)
            {
                int8 xGreatery = Operator.greater_mask_uint(x, y);
                int8 yGreaterx = Operator.greater_mask_uint(y, x);

                return((0 - xGreatery) + yGreaterx);
            }
            else
            {
                return(new int8(compareto(x.v4_0, y.v4_0),
                                compareto(x.v4_4, y.v4_4)));
            }
        }
        public static uint8 divrem(uint8 dividend, uint8 divisor, out uint8 remainder)
        {
            uint8 quotient = new uint8((uint)divrem((long)dividend.x0, (long)divisor.x0, out long x0),
                                       (uint)divrem((long)dividend.x1, (long)divisor.x1, out long x1),
                                       (uint)divrem((long)dividend.x2, (long)divisor.x2, out long x2),
                                       (uint)divrem((long)dividend.x3, (long)divisor.x3, out long x3),
                                       (uint)divrem((long)dividend.x4, (long)divisor.x4, out long x4),
                                       (uint)divrem((long)dividend.x5, (long)divisor.x5, out long x5),
                                       (uint)divrem((long)dividend.x6, (long)divisor.x6, out long x6),
                                       (uint)divrem((long)dividend.x7, (long)divisor.x7, out long x7));

            remainder = new uint8((uint)x0, (uint)x1, (uint)x2, (uint)x3, (uint)x4, (uint)x5, (uint)x6, (uint)x7);

            return(quotient);
        }
Beispiel #22
0
        public uint8 NextUInt8(uint8 max)
        {
            if (Avx2.IsAvx2Supported)
            {
                v256 hiProd_lo = Avx2.mm256_mul_epu32(new v256(NextState(), 0, NextState(), 0, NextState(), 0, NextState(), 0), (ulong4)max.v4_0);
                v256 hiProd_hi = Avx2.mm256_mul_epu32(new v256(NextState(), 0, NextState(), 0, NextState(), 0, NextState(), 0), (ulong4)max.v4_4);

                hiProd_lo = Avx2.mm256_permutevar8x32_epi32(hiProd_lo, Avx.mm256_castsi128_si256(new v128(1, 3, 5, 7)));
                hiProd_hi = Avx2.mm256_permutevar8x32_epi32(hiProd_hi, Avx.mm256_castsi128_si256(new v128(1, 3, 5, 7)));

                return(Avx.mm256_set_m128i(Avx.mm256_castsi256_si128(hiProd_hi), Avx.mm256_castsi256_si128(hiProd_lo)));
            }
            else
            {
                Unity.Mathematics.Random rng = this;

                return(new uint8(rng.NextUInt4(max.v4_0), rng.NextUInt4(max.v4_4)));
            }
        }
        public static int8 intpow(int8 x, uint8 n)
        {
            if (Avx2.IsAvx2Supported)
            {
                int8 ZERO = int8.zero;
                v256 ONE  = new int8(1);

                v256 doneMask = ZERO;
                v256 result   = ZERO;

                int8 p = x;
                int8 y = ONE;


Loop:
                v256 y_times_p = y * p;
                y = Avx2.mm256_blendv_epi8(y, y_times_p, Avx2.mm256_cmpeq_epi32(ONE, ONE & n));

                n >>= 1;

                v256 n_is_zero = Avx2.mm256_cmpeq_epi32(ZERO, n);
                result   = Avx2.mm256_blendv_epi8(result, y, Avx2.mm256_andnot_si256(doneMask, n_is_zero));
                doneMask = n_is_zero;


                if (-1 != Avx2.mm256_movemask_epi8(doneMask))
                {
                    p *= p;

                    goto Loop;
                }
                else
                {
                    return(result);
                }
            }
            else
            {
                return(new int8(intpow(x.v4_0, n.v4_0), intpow(x.v4_4, n.v4_4)));
            }
        }
Beispiel #24
0
        public static bool8 isdivisible(ushort8 dividend, ushort divisor)
        {
            Assert.AreNotEqual(0, divisor);

            if (Constant.IsConstantExpression(divisor))
            {
                if (math.ispow2((uint)divisor))
                {
                    return((dividend & (ushort)(divisor - 1)) == 0);
                }
                else
                {
                    uint8 compile = (new uint8(uint.MaxValue) / divisor) + 1;

                    return(dividend * compile <= compile - 1);
                }
            }
            else
            {
                return(dividend % divisor == 0);
            }
        }
Beispiel #25
0
        public static bool8 isdivisible(ushort8 dividend, ushort8 divisor)
        {
            Assert.AreNotEqual(0, divisor.x0);
            Assert.AreNotEqual(0, divisor.x1);
            Assert.AreNotEqual(0, divisor.x2);
            Assert.AreNotEqual(0, divisor.x3);
            Assert.AreNotEqual(0, divisor.x4);
            Assert.AreNotEqual(0, divisor.x5);
            Assert.AreNotEqual(0, divisor.x6);
            Assert.AreNotEqual(0, divisor.x7);

            if (Constant.IsConstantExpression(divisor))
            {
                uint8 compile = (new uint8(uint.MaxValue) / divisor) + 1;

                return(dividend * compile <= compile - 1);
            }
            else
            {
                return(dividend % divisor == 0);
            }
        }
Beispiel #26
0
        public static bool8 isdivisible(uint8 dividend, uint divisor)
        {
            Assert.AreNotEqual(0u, divisor);

            if (Constant.IsConstantExpression(divisor))
            {
                if (math.ispow2(divisor))
                {
                    return((dividend & (divisor - 1)) == 0);
                }
                else
                {
                    ulong4 compile = (new ulong4(ulong.MaxValue) / divisor) + 1;

                    return(new bool8(dividend.v4_0 * compile <= compile - 1,
                                     dividend.v4_4 * compile <= compile - 1));
                }
            }
            else
            {
                return(dividend % divisor == 0);
            }
        }
Beispiel #27
0
        public static bool8 isdivisible(uint8 dividend, uint8 divisor)
        {
            Assert.AreNotEqual(0u, divisor.x0);
            Assert.AreNotEqual(0u, divisor.x1);
            Assert.AreNotEqual(0u, divisor.x2);
            Assert.AreNotEqual(0u, divisor.x3);
            Assert.AreNotEqual(0u, divisor.x4);
            Assert.AreNotEqual(0u, divisor.x5);
            Assert.AreNotEqual(0u, divisor.x6);
            Assert.AreNotEqual(0u, divisor.x7);

            if (Constant.IsConstantExpression(divisor))
            {
                ulong4 compile_lo = (new ulong4(ulong.MaxValue) / divisor.v4_0) + 1;
                ulong4 compile_hi = (new ulong4(ulong.MaxValue) / divisor.v4_4) + 1;

                return(new bool8(dividend.v4_0 * compile_lo <= compile_lo - 1,
                                 dividend.v4_4 * compile_lo <= compile_lo - 1));
            }
            else
            {
                return(dividend % divisor == 0);
            }
        }
Beispiel #28
0
 public static uint cmin(uint8 x)
 {
     return(math.cmin(math.min(x.v4_0, x.v4_4)));
 }
Beispiel #29
0
 public static uint8 clamp(uint8 x, uint8 a, uint8 b)
 {
     return(max(a, min(x, b)));
 }
Beispiel #30
0
 public static uint8 countbits(uint8 x)
 {
     x -= (x >> 1) & 0x5555_5555;
     x  = (x & 0x3333_3333) + ((x >> 2) & 0x3333_3333);
     return((((x + (x >> 4)) & 0x0F0F_0F0F) * 0x0101_0101) >> 24);
 }