libnx v4.9.0
Loading...
Searching...
No Matches
crc.h
Go to the documentation of this file.
1/**
2 * @file crc.h
3 * @brief Hardware accelerated CRC32 implementation.
4 * @copyright libnx Authors
5 */
6#pragma once
7#include <arm_acle.h>
8#include "../types.h"
9
10#define _CRC_ALIGN(sz, insn) \
11do { \
12 if (((uintptr_t)src_u8 & sizeof(sz)) && (u64)len >= sizeof(sz)) { \
13 crc = __crc32##insn(crc, *((const sz *)src_u8)); \
14 src_u8 += sizeof(sz); \
15 len -= sizeof(sz); \
16 } \
17} while (0)
18
19#define _CRC_REMAINDER(sz, insn) \
20do { \
21 if (len & sizeof(sz)) { \
22 crc = __crc32##insn(crc, *((const sz *)src_u8)); \
23 src_u8 += sizeof(sz); \
24 } \
25} while (0)
26
27/// Calculate a CRC32 over data using a seed.
28/// Can be used to calculate a CRC32 in chunks using an initial seed of zero for the first chunk.
29static inline u32 crc32CalculateWithSeed(u32 seed, const void *src, size_t size) {
30 const u8 *src_u8 = (const u8 *)src;
31
32 u32 crc = ~seed;
33 s64 len = size;
34
35 _CRC_ALIGN(u8, b);
36 _CRC_ALIGN(u16, h);
37 _CRC_ALIGN(u32, w);
38
39 while ((len -= sizeof(u64)) >= 0) {
40 crc = __crc32d(crc, *((const u64 *)src_u8));
41 src_u8 += sizeof(u64);
42 }
43
44 _CRC_REMAINDER(u32, w);
45 _CRC_REMAINDER(u16, h);
46 _CRC_REMAINDER(u8, b);
47
48 return ~crc;
49}
50
51/// Calculate a CRC32 over data.
52static inline u32 crc32Calculate(const void *src, size_t size) {
53 return crc32CalculateWithSeed(0, src, size);
54}
55
56/// Calculate a CRC32C over data using a seed.
57/// Can be used to calculate a CRC32C in chunks using an initial seed of zero for the first chunk.
58static inline u32 crc32cCalculateWithSeed(u32 seed, const void *src, size_t size) {
59 const u8 *src_u8 = (const u8 *)src;
60
61 u32 crc = ~seed;
62 s64 len = size;
63
64 _CRC_ALIGN(u8, cb);
65 _CRC_ALIGN(u16, ch);
66 _CRC_ALIGN(u32, cw);
67
68 while ((len -= sizeof(u64)) >= 0) {
69 crc = __crc32cd(crc, *((const u64 *)src_u8));
70 src_u8 += sizeof(u64);
71 }
72
73 _CRC_REMAINDER(u32, cw);
74 _CRC_REMAINDER(u16, ch);
75 _CRC_REMAINDER(u8, cb);
76
77 return ~crc;
78}
79
80/// Calculate a CRC32C over data.
81static inline u32 crc32cCalculate(const void *src, size_t size) {
82 return crc32cCalculateWithSeed(0, src, size);
83}
84
85#undef _CRC_REMAINDER
86#undef _CRC_ALIGN
static u32 crc32cCalculateWithSeed(u32 seed, const void *src, size_t size)
Calculate a CRC32C over data using a seed.
Definition crc.h:58
static u32 crc32Calculate(const void *src, size_t size)
Calculate a CRC32 over data.
Definition crc.h:52
static u32 crc32cCalculate(const void *src, size_t size)
Calculate a CRC32C over data.
Definition crc.h:81
static u32 crc32CalculateWithSeed(u32 seed, const void *src, size_t size)
Calculate a CRC32 over data using a seed.
Definition crc.h:29
int64_t s64
64-bit signed integer.
Definition types.h:28
uint64_t u64
64-bit unsigned integer.
Definition types.h:22
uint8_t u8
8-bit unsigned integer.
Definition types.h:19
uint16_t u16
16-bit unsigned integer.
Definition types.h:20
uint32_t u32
32-bit unsigned integer.
Definition types.h:21