/* * This file is part of the Aaru Data Preservation Suite. * Copyright (c) 2019-2021 Natalia Portillo. * Copyright 2017 The Chromium Authors. All rights reserved. * * 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. */ #if(defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM)) && __ARM_ARCH >= 8 #include #include "library.h" #include "crc32.h" TARGET_ARMV8_WITH_CRC uint32_t armv8_crc32_little(uint32_t previous_crc, const uint8_t* data, uint32_t len) { uint32_t c = (uint32_t)previous_crc; #if defined(__aarch64__) || defined(_M_ARM64) while(len && ((uintptr_t)data & 7)) { c = __crc32b(c, *data++); --len; } const uint64_t* buf8 = (const uint64_t*)data; while(len >= 64) { c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); c = __crc32d(c, *buf8++); len -= 64; } while(len >= 8) { c = __crc32d(c, *buf8++); len -= 8; } data = (const uint8_t*)buf8; #else // AARCH64 while(len && ((uintptr_t)buf & 3)) { c = __crc32b(c, *buf++); --len; } const uint32_t* buf4 = (const uint32_t*)buf; while(len >= 32) { c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); c = __crc32w(c, *buf4++); len -= 32; } while(len >= 4) { c = __crc32d(c, *buf4++); len -= 4; } buf = (const uint8_t*)buf4; #endif while(len--) { c = __crc32b(c, *data++); } return c; } #endif