예제 #1
0
        private static uint ExtractCharsFromFourByteSequence(uint value)
        {
            if (BitConverter.IsLittleEndian)
            {
#if NETCOREAPP3_1
                if (Bmi2.IsSupported)
                {
                    // need to reverse endianness for bit manipulation to work correctly
                    value = BinaryPrimitives.ReverseEndianness(value);

                    // value = [ 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ]
                    // want to return [ 110110wwwwxxxxxx 110111xxxxxxxxxx ]
                    // where wwww = uuuuu - 1

                    uint highSurrogateChar = Bmi2.ParallelBitExtract(value, 0b00000111_00111111_00110000_00000000u);
                    uint lowSurrogateChar  = Bmi2.ParallelBitExtract(value, 0b00000000_00000000_00001111_00111111u);

                    uint combined = (lowSurrogateChar << 16) + highSurrogateChar;
                    combined -= 0x40u;        // wwww = uuuuu - 1
                    combined += 0xDC00_D800u; // add surrogate markers
                    return(combined);
                }
                else
                {
#endif
                // input is UTF8 [ 10xxxxxx 10yyyyyy 10uuzzzz 11110uuu ] = scalar 000uuuuu zzzzyyyy yyxxxxxx
                // want to return UTF16 scalar 000uuuuuzzzzyyyyyyxxxxxx = [ 110111yy yyxxxxxx 110110ww wwzzzzyy ]
                // where wwww = uuuuu - 1
                uint retVal = (uint)(byte)value << 8;   // retVal = [ 00000000 00000000 11110uuu 00000000 ]
                retVal |= (value & 0x0000_3F00u) >> 6;  // retVal = [ 00000000 00000000 11110uuu uuzzzz00 ]
                retVal |= (value & 0x0030_0000u) >> 20; // retVal = [ 00000000 00000000 11110uuu uuzzzzyy ]
                retVal |= (value & 0x3F00_0000u) >> 8;  // retVal = [ 00000000 00xxxxxx 11110uuu uuzzzzyy ]
                retVal |= (value & 0x000F_0000u) << 6;  // retVal = [ 000000yy yyxxxxxx 11110uuu uuzzzzyy ]
                retVal -= 0x0000_0040u;                 // retVal = [ 000000yy yyxxxxxx 111100ww wwzzzzyy ]
                retVal -= 0x0000_2000u;                 // retVal = [ 000000yy yyxxxxxx 110100ww wwzzzzyy ]
                retVal += 0x0000_0800u;                 // retVal = [ 000000yy yyxxxxxx 110110ww wwzzzzyy ]
                retVal += 0xDC00_0000u;                 // retVal = [ 110111yy yyxxxxxx 110110ww wwzzzzyy ]
                return(retVal);

#if NETCOREAPP3_1
            }
#endif
            }
            else
            {
                // input is UTF8 [ 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx ] = scalar 000uuuuu zzzzyyyy yyxxxxxx
                // want to return UTF16 scalar 000uuuuuxxxxxxxxxxxxxxxx = [ 110110wwwwxxxxxx 110111xxxxxxxxx ]
                // where wwww = uuuuu - 1
                uint retVal = value & 0xFF00_0000u;    // retVal = [ 11110uuu 00000000 00000000 00000000 ]
                retVal |= (value & 0x003F_0000u) << 2; // retVal = [ 11110uuu uuzzzz00 00000000 00000000 ]
                retVal |= (value & 0x0000_3000u) << 4; // retVal = [ 11110uuu uuzzzzyy 00000000 00000000 ]
                retVal |= (value & 0x0000_0F00u) >> 2; // retVal = [ 11110uuu uuzzzzyy 000000yy yy000000 ]
                retVal |= (value & 0x0000_003Fu);      // retVal = [ 11110uuu uuzzzzyy 000000yy yyxxxxxx ]
                retVal -= 0x2000_0000u;                // retVal = [ 11010uuu uuzzzzyy 000000yy yyxxxxxx ]
                retVal -= 0x0040_0000u;                // retVal = [ 110100ww wwzzzzyy 000000yy yyxxxxxx ]
                retVal += 0x0000_DC00u;                // retVal = [ 110100ww wwzzzzyy 110111yy yyxxxxxx ]
                retVal += 0x0800_0000u;                // retVal = [ 110110ww wwzzzzyy 110111yy yyxxxxxx ]
                return(retVal);
            }
        }
예제 #2
0
        public void RunStructLclFldScenario()
        {
            var test   = TestStruct.Create();
            var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);

            ValidateResult(test._fld1, test._fld2, result);
        }
예제 #3
0
        public void RunClassLclFldScenario()
        {
            var test   = new ScalarBinaryOpTest__ParallelBitExtractUInt64();
            var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);

            ValidateResult(test._fld1, test._fld2, result);
        }
예제 #4
0
        public void RunLclVarScenario_UnsafeRead()
        {
            var data1  = Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data1));
            var data2  = Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data2));
            var result = Bmi2.ParallelBitExtract(data1, data2);

            ValidateResult(data1, data2, result);
        }
예제 #5
0
        public void RunClassFldScenario()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));

            var result = Bmi2.ParallelBitExtract(_fld1, _fld2);

            ValidateResult(_fld1, _fld2, result);
        }
 public static uint ParallelBitExtract(uint x, uint mask)
 {
     if (Bmi2.IsSupported)
     {
         return(Bmi2.ParallelBitExtract(x, mask));
     }
     return(ParallelBitExtractLogic(x, mask));
 }
예제 #7
0
        public void RunClsVarScenario()
        {
            var result = Bmi2.ParallelBitExtract(
                _clsVar1,
                _clsVar2
                );

            ValidateResult(_clsVar1, _clsVar2, result);
        }
예제 #8
0
        public void RunBasicScenario_UnsafeRead()
        {
            var result = Bmi2.ParallelBitExtract(
                Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data1)),
                Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data2))
                );

            ValidateResult(_data1, _data2, result);
        }
예제 #9
0
        public void RunStructLclFldScenario()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));

            var test   = TestStruct.Create();
            var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);

            ValidateResult(test._fld1, test._fld2, result);
        }
예제 #10
0
        public void RunClassLclFldScenario()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));

            var test   = new ScalarBinaryOpTest__ParallelBitExtractUInt32();
            var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);

            ValidateResult(test._fld1, test._fld2, result);
        }
예제 #11
0
        public void RunLclVarScenario_UnsafeRead()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));

            var data1  = Unsafe.ReadUnaligned <UInt32>(ref Unsafe.As <UInt32, byte>(ref _data1));
            var data2  = Unsafe.ReadUnaligned <UInt32>(ref Unsafe.As <UInt32, byte>(ref _data2));
            var result = Bmi2.ParallelBitExtract(data1, data2);

            ValidateResult(data1, data2, result);
        }
예제 #12
0
        public void RunClsVarScenario()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));

            var result = Bmi2.ParallelBitExtract(
                _clsVar1,
                _clsVar2
                );

            ValidateResult(_clsVar1, _clsVar2, result);
        }
예제 #13
0
        public void RunBasicScenario_UnsafeRead()
        {
            TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));

            var result = Bmi2.ParallelBitExtract(
                Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data1)),
                Unsafe.ReadUnaligned <UInt64>(ref Unsafe.As <UInt64, byte>(ref _data2))
                );

            ValidateResult(_data1, _data2, result);
        }
        public override ulong Run(CancellationToken cancellationToken)
        {
            if (!Bmi2.IsSupported)
            {
                return(0uL);
            }

            var iterations = 0uL;
            var zhb        = randomInt;

            while (!cancellationToken.IsCancellationRequested)
            {
                for (var i = 0; i < LENGTH; i++)
                {
                    zhb = Bmi2.ParallelBitExtract(zhb, anotherRandomInt);
                }

                iterations++;
            }

            return(iterations + zhb - zhb);
        }
예제 #15
0
            public void RunStructFldScenario(ScalarBinaryOpTest__ParallelBitExtractUInt64 testClass)
            {
                var result = Bmi2.ParallelBitExtract(_fld1, _fld2);

                testClass.ValidateResult(_fld1, _fld2, result);
            }
예제 #16
0
        public void RunClassFldScenario()
        {
            var result = Bmi2.ParallelBitExtract(_fld1, _fld2);

            ValidateResult(_fld1, _fld2, result);
        }