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