mirror of
https://github.com/apache/nuttx.git
synced 2026-05-26 18:56:10 +08:00
libc/arm: optimize crc32/crc32c for arm
Optimize crc32 standard(poly:0x04C11DB7) and crc32 castagnoli(poly:0x1EDC6F41) with arm crc32 extension instructions. For example, crc32 standard caculates(lookup crc32 table) 1812 bytes data, reduced the time from 118 us to 14 us through optimization. Performance improved ~700% Signed-off-by: Jinliang Li <lijinliang1@lixiang.com>
This commit is contained in:
committed by
Alan C. Assis
parent
586d216a40
commit
d5db7d1cee
@@ -68,4 +68,8 @@ if(CONFIG_PROFILE_MINI)
|
||||
list(APPEND SRCS gnu/mcount.S)
|
||||
endif()
|
||||
|
||||
if(CONFIG_LIBC_ARCH_CRC32)
|
||||
list(APPEND SRCS arch_crc32.c)
|
||||
endif()
|
||||
|
||||
target_sources(c PRIVATE ${SRCS})
|
||||
|
||||
@@ -31,3 +31,10 @@ endif
|
||||
if ARCH_ARMV8R
|
||||
source "libs/libc/machine/arm/armv8-r/Kconfig"
|
||||
endif
|
||||
|
||||
config LIBC_ARCH_CRC32
|
||||
bool "Enable optimized crc32 for ARM"
|
||||
default n
|
||||
depends on ARCH_HAVE_CRC32
|
||||
---help---
|
||||
Enable optimized arm neon specific crc32 library function
|
||||
|
||||
@@ -66,6 +66,10 @@ ifeq ($(CONFIG_PROFILE_MINI),y)
|
||||
ASRCS += mcount.S
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LIBC_ARCH_CRC32),y)
|
||||
CSRCS += arch_crc32.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_TOOLCHAIN_GNU),y)
|
||||
DEPPATH += --dep-path machine/arm/gnu
|
||||
VPATH += :machine/arm/gnu
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
* libs/libc/machine/arm/arch_crc32.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <arm_acle.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: crc32part
|
||||
*
|
||||
* Description:
|
||||
* crc32 polynomial 0x04C11DB7 (bitreflected 0xEDB88320)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t crc32part(FAR const uint8_t *src, size_t len, uint32_t crc32val)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (; (i + 8) <= len; i += 8)
|
||||
{
|
||||
uint64_t data = *(uint64_t *)(src + i);
|
||||
crc32val = __crc32d(crc32val, data);
|
||||
}
|
||||
|
||||
if (i + 4 <= len)
|
||||
{
|
||||
uint32_t data = *(uint32_t *)(src + i);
|
||||
crc32val = __crc32w(crc32val, data);
|
||||
i += 4;
|
||||
}
|
||||
|
||||
if (i + 2 <= len)
|
||||
{
|
||||
uint16_t data = *(uint16_t *)(src + i);
|
||||
crc32val = __crc32h(crc32val, data);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
uint8_t data = *(uint8_t *)(src + i);
|
||||
crc32val = __crc32b(crc32val, data);
|
||||
}
|
||||
|
||||
return crc32val;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: crc32part_c
|
||||
*
|
||||
* Description:
|
||||
* crc32 Castagnoli polynomial 0x1EDC6F41
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t crc32part_c(FAR const uint8_t *src, size_t len, uint32_t crc32val)
|
||||
{
|
||||
size_t i = 0;
|
||||
|
||||
for (; (i + 8) <= len; i += 8)
|
||||
{
|
||||
uint64_t data = *(uint64_t *)(src + i);
|
||||
crc32val = __crc32cd(crc32val, data);
|
||||
}
|
||||
|
||||
if (i + 4 <= len)
|
||||
{
|
||||
uint32_t data = *(uint32_t *)(src + i);
|
||||
crc32val = __crc32cw(crc32val, data);
|
||||
i += 4;
|
||||
}
|
||||
|
||||
if (i + 2 <= len)
|
||||
{
|
||||
uint16_t data = *(uint16_t *)(src + i);
|
||||
crc32val = __crc32ch(crc32val, data);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
uint8_t data = *(uint8_t *)(src + i);
|
||||
crc32val = __crc32cb(crc32val, data);
|
||||
}
|
||||
|
||||
return crc32val;
|
||||
}
|
||||
Reference in New Issue
Block a user