コード例 #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)));
            }
        }
コード例 #2
0
ファイル: Bitmask.cs プロジェクト: csritter/MaxMath
        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)));
            }
        }
コード例 #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);
            }
        }
コード例 #4
0
        public static uint8 lcm(int8 x, int8 y)
        {
            uint8 absX = (uint8)abs(x);
            uint8 absY = (uint8)abs(y);

            return((absX / gcd(absX, absY)) * absY);
        }
コード例 #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)));
            }
        }
コード例 #6
0
ファイル: Is Divisible.cs プロジェクト: csritter/MaxMath
        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);
            }
        }
コード例 #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)));
            }
        }
コード例 #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);
        }
コード例 #9
0
ファイル: Reverse Bits.cs プロジェクト: csritter/MaxMath
        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));
        }
コード例 #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));
        }
コード例 #11
0
ファイル: Bit Pattern.cs プロジェクト: csritter/MaxMath
 public static float8 asfloat(uint8 x)
 {
     if (Avx.IsAvxSupported)
     {
         return((v256)x);
     }
     else
     {
         return(*(float8 *)&x);
     }
 }
コード例 #12
0
ファイル: uint8.cs プロジェクト: csritter/MaxMath
 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;
 }
コード例 #13
0
ファイル: Max.cs プロジェクト: csritter/MaxMath
 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)));
     }
 }
コード例 #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);
        }
コード例 #15
0
ファイル: Subtract-Add.cs プロジェクト: csritter/MaxMath
 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)));
     }
 }
コード例 #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)));
     }
 }
コード例 #17
0
        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);
            }
        }
コード例 #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();
            }
        }
コード例 #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)));
            }
        }
コード例 #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)));
            }
        }
コード例 #21
0
        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);
        }
コード例 #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)));
            }
        }
コード例 #23
0
        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)));
            }
        }
コード例 #24
0
ファイル: Is Divisible.cs プロジェクト: csritter/MaxMath
        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);
            }
        }
コード例 #25
0
ファイル: Is Divisible.cs プロジェクト: csritter/MaxMath
        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);
            }
        }
コード例 #26
0
ファイル: Is Divisible.cs プロジェクト: csritter/MaxMath
        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);
            }
        }
コード例 #27
0
ファイル: Is Divisible.cs プロジェクト: csritter/MaxMath
        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);
            }
        }
コード例 #28
0
 public static uint cmin(uint8 x)
 {
     return(math.cmin(math.min(x.v4_0, x.v4_4)));
 }
コード例 #29
0
 public static uint8 clamp(uint8 x, uint8 a, uint8 b)
 {
     return(max(a, min(x, b)));
 }
コード例 #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);
 }