aboutsummaryrefslogtreecommitdiff
path: root/crc32.c
diff options
context:
space:
mode:
Diffstat (limited to 'crc32.c')
-rw-r--r--crc32.c126
1 files changed, 64 insertions, 62 deletions
diff --git a/crc32.c b/crc32.c
index 62cb9fe..5fab3f5 100644
--- a/crc32.c
+++ b/crc32.c
@@ -101,11 +101,41 @@
101/* Local functions. */ 101/* Local functions. */
102local z_crc_t multmodp OF((z_crc_t a, z_crc_t b)); 102local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
103local z_crc_t x2nmodp OF((z_off64_t n, unsigned k)); 103local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
104#ifdef W 104
105 local z_word_t byte_swap OF((z_word_t word)); 105/* If available, use the ARM processor CRC32 instruction. */
106 local z_crc_t crc_word OF((z_word_t data)); 106#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
107 local z_word_t crc_word_big OF((z_word_t data)); 107# define ARMCRC32
108#endif /* W */ 108#endif
109
110#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
111/*
112 Swap the bytes in a z_word_t to convert between little and big endian. Any
113 self-respecting compiler will optimize this to a single machine byte-swap
114 instruction, if one is available. This assumes that word_t is either 32 bits
115 or 64 bits.
116 */
117local z_word_t byte_swap(word)
118 z_word_t word;
119{
120# if W == 8
121 return
122 (word & 0xff00000000000000) >> 56 |
123 (word & 0xff000000000000) >> 40 |
124 (word & 0xff0000000000) >> 24 |
125 (word & 0xff00000000) >> 8 |
126 (word & 0xff000000) << 8 |
127 (word & 0xff0000) << 24 |
128 (word & 0xff00) << 40 |
129 (word & 0xff) << 56;
130# else /* W == 4 */
131 return
132 (word & 0xff000000) >> 24 |
133 (word & 0xff0000) >> 8 |
134 (word & 0xff00) << 8 |
135 (word & 0xff) << 24;
136# endif
137}
138#endif
109 139
110/* CRC polynomial. */ 140/* CRC polynomial. */
111#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ 141#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */
@@ -549,62 +579,6 @@ local z_crc_t x2nmodp(n, k)
549 return p; 579 return p;
550} 580}
551 581
552#ifdef W
553
554/*
555 Swap the bytes in a z_word_t to convert between little and big endian. Any
556 self-respecting compiler will optimize this to a single machine byte-swap
557 instruction, if one is available. This assumes that word_t is either 32 bits
558 or 64 bits.
559 */
560local z_word_t byte_swap(word)
561 z_word_t word;
562{
563#if W == 8
564 return
565 (word & 0xff00000000000000) >> 56 |
566 (word & 0xff000000000000) >> 40 |
567 (word & 0xff0000000000) >> 24 |
568 (word & 0xff00000000) >> 8 |
569 (word & 0xff000000) << 8 |
570 (word & 0xff0000) << 24 |
571 (word & 0xff00) << 40 |
572 (word & 0xff) << 56;
573#else /* W == 4 */
574 return
575 (word & 0xff000000) >> 24 |
576 (word & 0xff0000) >> 8 |
577 (word & 0xff00) << 8 |
578 (word & 0xff) << 24;
579#endif
580}
581
582/*
583 Return the CRC of the W bytes in the word_t data, taking the
584 least-significant byte of the word as the first byte of data, without any pre
585 or post conditioning. This is used to combine the CRCs of each braid.
586 */
587local z_crc_t crc_word(data)
588 z_word_t data;
589{
590 int k;
591 for (k = 0; k < W; k++)
592 data = (data >> 8) ^ crc_table[data & 0xff];
593 return (z_crc_t)data;
594}
595
596local z_word_t crc_word_big(data)
597 z_word_t data;
598{
599 int k;
600 for (k = 0; k < W; k++)
601 data = (data << 8) ^
602 crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
603 return data;
604}
605
606#endif /* W */
607
608/* ========================================================================= 582/* =========================================================================
609 * This function can be used by asm versions of crc32(), and to force the 583 * This function can be used by asm versions of crc32(), and to force the
610 * generation of the CRC tables in a threaded application. 584 * generation of the CRC tables in a threaded application.
@@ -626,7 +600,7 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
626 * -march=armv8-a+crc, or -march=native if the compile machine has the crc32 600 * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
627 * instructions. 601 * instructions.
628 */ 602 */
629#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8 603#ifdef ARMCRC32
630 604
631/* 605/*
632 Constants empirically determined to maximize speed. These values are from 606 Constants empirically determined to maximize speed. These values are from
@@ -733,6 +707,34 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
733 707
734#else 708#else
735 709
710#ifdef W
711
712/*
713 Return the CRC of the W bytes in the word_t data, taking the
714 least-significant byte of the word as the first byte of data, without any pre
715 or post conditioning. This is used to combine the CRCs of each braid.
716 */
717local z_crc_t crc_word(data)
718 z_word_t data;
719{
720 int k;
721 for (k = 0; k < W; k++)
722 data = (data >> 8) ^ crc_table[data & 0xff];
723 return (z_crc_t)data;
724}
725
726local z_word_t crc_word_big(data)
727 z_word_t data;
728{
729 int k;
730 for (k = 0; k < W; k++)
731 data = (data << 8) ^
732 crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
733 return data;
734}
735
736#endif
737
736/* ========================================================================= */ 738/* ========================================================================= */
737unsigned long ZEXPORT crc32_z(crc, buf, len) 739unsigned long ZEXPORT crc32_z(crc, buf, len)
738 unsigned long crc; 740 unsigned long crc;