diff --git a/Aaru6.Checksums/Aaru6.Checksums.csproj b/Aaru6.Checksums/Aaru6.Checksums.csproj index bc3e4fd..20ad09d 100644 --- a/Aaru6.Checksums/Aaru6.Checksums.csproj +++ b/Aaru6.Checksums/Aaru6.Checksums.csproj @@ -58,6 +58,7 @@ + diff --git a/Aaru6.Checksums/CRC32/arm_simd.cs b/Aaru6.Checksums/CRC32/arm_simd.cs new file mode 100644 index 0000000..d3823f3 --- /dev/null +++ b/Aaru6.Checksums/CRC32/arm_simd.cs @@ -0,0 +1,139 @@ +// /*************************************************************************** +// Aaru Data Preservation Suite +// ---------------------------------------------------------------------------- +// +// Filename : arm_simd.cs +// Author(s) : Natalia Portillo +// The Chromium Authors +// +// Component : Checksums. +// +// --[ Description ] ---------------------------------------------------------- +// +// Compute CRC32 checksum using ARM special instructions.. +// +// --[ License ] -------------------------------------------------------------- +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// ---------------------------------------------------------------------------- +// Copyright © 2011-2021 Natalia Portillo +// Copyright 2017 The Chromium Authors. All rights reserved. +// ****************************************************************************/ + +using System; +using System.Runtime.Intrinsics.Arm; + +namespace Aaru6.Checksums.CRC32 +{ + internal static class ArmSimd + { + internal static uint Step64(byte[] buf, long len, uint crc) + { + uint c = crc; + + int bufPos = 0; + + while(len >= 64) + { + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + len -= 64; + } + + while(len >= 8) + { + c = Crc32.Arm64.ComputeCrc32(c, BitConverter.ToUInt64(buf, bufPos)); + bufPos += 8; + len -= 8; + } + + while(len-- > 0) + { + c = Crc32.ComputeCrc32(c, buf[bufPos++]); + } + + return c; + } + + internal static uint Step32(byte[] buf, long len, uint crc) + { + uint c = crc; + + int bufPos = 0; + + while(len >= 32) + { + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + len -= 32; + } + + while(len >= 4) + { + c = Crc32.ComputeCrc32(c, BitConverter.ToUInt32(buf, bufPos)); + bufPos += 4; + len -= 4; + } + + while(len-- > 0) + { + c = Crc32.ComputeCrc32(c, buf[bufPos++]); + } + + return c; + } + } +} \ No newline at end of file diff --git a/Aaru6.Checksums/CRC32Context.cs b/Aaru6.Checksums/CRC32Context.cs index ce1d95c..56a6e5a 100644 --- a/Aaru6.Checksums/CRC32Context.cs +++ b/Aaru6.Checksums/CRC32Context.cs @@ -32,6 +32,7 @@ using System; using System.IO; +using System.Runtime.Intrinsics.Arm; using System.Runtime.Intrinsics.X86; using System.Text; using Aaru.CommonTypes.Interfaces; @@ -411,15 +412,31 @@ namespace Aaru6.Checksums static void Step(ref uint previousCrc, uint[][] table, byte[] data, uint len, bool useIso) { - if(useIso && - Pclmulqdq.IsSupported && - Sse41.IsSupported && - Ssse3.IsSupported && - Sse2.IsSupported) + if(useIso) { - previousCrc = ~Clmul.Step(data, len, ~previousCrc); + if(Pclmulqdq.IsSupported && + Sse41.IsSupported && + Ssse3.IsSupported && + Sse2.IsSupported) + { + previousCrc = ~Clmul.Step(data, len, ~previousCrc); - return; + return; + } + + if(Crc32.Arm64.IsSupported) + { + previousCrc = ArmSimd.Step64(data, len, previousCrc); + + return; + } + + if(Crc32.IsSupported) + { + previousCrc = ArmSimd.Step32(data, len, previousCrc); + + return; + } } // Unroll according to Intel slicing by uint8_t