The calculate_crc and calculate_reversed_crc functions assumed initial
crc of 0 and only operated on 8 bits of data. This commit extends those
functions to take explicit data arg and data size as well, so that it
can compute CRC for >8 bits with a separate initial CRC.
These functions are also made public so that they can be called from
different modules. This will be used in the future to implement CRC
const folding.
gcc/ChangeLog:
* expr.cc (calculate_crc): Moved to hwint.cc file.
(assemble_crc_table): Updated function call.
(calculate_reversed_crc): Moved to hwint.cc file.
(assemble_reversed_crc_table): Updated function call.
* hwint.cc (calculate_crc): Moved from expr.cc and made public.
(calculate_reversed_crc): Moved from expr.cc and made public.
* hwint.h (calculate_crc): Added function prototype.
(calculate_reversed_crc): Added function prototype.
Signed-off-by: Shreesh Adiga <[email protected]>
---
Changes in v3:
moved the crc functions to hwint.cc
added asserts for crc functions
gcc/expr.cc | 50 +++-------------------------------------
gcc/hwint.cc | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++
gcc/hwint.h | 13 +++++++++++
3 files changed, 80 insertions(+), 47 deletions(-)
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 0a7013e3a25..3d99be8472f 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -14581,29 +14581,6 @@ gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT
polynomial,
return quotient;
}
-/* Calculate CRC for the initial CRC and given POLYNOMIAL.
- CRC_BITS is CRC size. */
-
-static unsigned HOST_WIDE_INT
-calculate_crc (unsigned HOST_WIDE_INT crc,
- unsigned HOST_WIDE_INT polynomial,
- unsigned short crc_bits)
-{
- unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
- crc = crc << (crc_bits - 8);
- for (short i = 8; i > 0; --i)
- {
- if (crc & msb)
- crc = (crc << 1) ^ polynomial;
- else
- crc <<= 1;
- }
- /* Zero out bits in crc beyond the specified number of crc_bits. */
- if (crc_bits < sizeof (crc) * CHAR_BIT)
- crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
- return crc;
-}
-
/* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
POLYNOM is the polynomial used to calculate the CRC table's elements.
CRC_BITS is the size of CRC, may be 8, 16, ... . */
@@ -14620,7 +14597,7 @@ assemble_crc_table (unsigned HOST_WIDE_INT polynom,
unsigned short crc_bits)
vec_alloc (initial_values, table_el_n);
for (size_t i = 0; i < table_el_n; ++i)
{
- unsigned HOST_WIDE_INT crc = calculate_crc (i, polynom, crc_bits);
+ unsigned HOST_WIDE_INT crc = calculate_crc (0, i, polynom, crc_bits, 8);
tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
vec_safe_push (initial_values, element);
}
@@ -14654,28 +14631,6 @@ generate_crc_table (unsigned HOST_WIDE_INT polynom,
unsigned short crc_bits)
return assemble_crc_table (polynom, crc_bits);
}
-/* Calculate CRC for the initial CRC and given POLYNOMIAL.
- CRC_BITS is CRC size. */
-
-static unsigned HOST_WIDE_INT
-calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
- unsigned HOST_WIDE_INT polynomial,
- unsigned short crc_bits)
-{
- unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
- for (int j = 0; j < 8; j++)
- {
- if (crc & 1)
- crc = (crc >> 1) ^ rev_polynom;
- else
- crc >>= 1;
- }
- /* Zero out bits in crc beyond the specified number of crc_bits. */
- if (crc_bits < sizeof (crc) * CHAR_BIT)
- crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
- return crc;
-}
-
/* Assemble CRC table with 256 elements for the given POLYNOM and CRC_BITS.
POLYNOM is the polynomial used to calculate the CRC table's elements.
CRC_BITS is the size of CRC, may be 8, 16, ... . */
@@ -14692,7 +14647,8 @@ assemble_reversed_crc_table (unsigned HOST_WIDE_INT
polynom, unsigned short crc_
vec_alloc (initial_values, table_el_n);
for (size_t i = 0; i < table_el_n; ++i)
{
- unsigned HOST_WIDE_INT crc = calculate_reversed_crc (i, polynom,
crc_bits);
+ unsigned HOST_WIDE_INT crc = calculate_reversed_crc (0, i, polynom,
+ crc_bits, 8);
tree element = build_int_cstu (make_unsigned_type (crc_bits), crc);
vec_safe_push (initial_values, element);
}
diff --git a/gcc/hwint.cc b/gcc/hwint.cc
index da7bc05f085..065911d0a77 100644
--- a/gcc/hwint.cc
+++ b/gcc/hwint.cc
@@ -217,3 +217,67 @@ reflect_hwi (unsigned HOST_WIDE_INT value, unsigned
bitwidth)
return reflected_value;
#endif
}
+
+/* Calculate CRC for the initial CRC, DATA and given POLYNOMIAL.
+ CRC_BITS is CRC size and DATA_BITS is the data size. */
+
+unsigned HOST_WIDE_INT
+calculate_crc (unsigned HOST_WIDE_INT crc,
+ unsigned HOST_WIDE_INT data,
+ unsigned HOST_WIDE_INT polynomial,
+ unsigned short crc_bits,
+ unsigned short data_bits)
+{
+ if (data_bits == 0)
+ return crc;
+
+ gcc_checking_assert (crc_bits <= 64);
+ gcc_checking_assert (data_bits <= 64);
+ gcc_checking_assert (crc_bits >= data_bits);
+
+ unsigned HOST_WIDE_INT msb = HOST_WIDE_INT_1U << (crc_bits - 1);
+ crc ^= (data << (crc_bits - data_bits));
+ for (short i = data_bits; i > 0; --i)
+ {
+ if (crc & msb)
+ crc = (crc << 1) ^ polynomial;
+ else
+ crc <<= 1;
+ }
+ /* Zero out bits in crc beyond the specified number of crc_bits. */
+ if (crc_bits < HOST_BITS_PER_WIDE_INT)
+ crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
+ return crc;
+}
+
+/* Calculate CRC for the initial CRC, DATA and given POLYNOMIAL.
+ CRC_BITS is CRC size and DATA_BITS is the DATA size. */
+
+unsigned HOST_WIDE_INT
+calculate_reversed_crc (unsigned HOST_WIDE_INT crc,
+ unsigned HOST_WIDE_INT data,
+ unsigned HOST_WIDE_INT polynomial,
+ unsigned short crc_bits,
+ unsigned short data_bits)
+{
+ if (data_bits == 0)
+ return crc;
+
+ gcc_checking_assert (crc_bits <= 64);
+ gcc_checking_assert (data_bits <= 64);
+ gcc_checking_assert (crc_bits >= data_bits);
+
+ unsigned HOST_WIDE_INT rev_polynom = reflect_hwi (polynomial, crc_bits);
+ crc ^= data;
+ for (int j = 0; j < data_bits; j++)
+ {
+ if (crc & 1)
+ crc = (crc >> 1) ^ rev_polynom;
+ else
+ crc >>= 1;
+ }
+ /* Zero out bits in crc beyond the specified number of crc_bits. */
+ if (crc_bits < HOST_BITS_PER_WIDE_INT)
+ crc &= (HOST_WIDE_INT_1U << crc_bits) - 1;
+ return crc;
+}
diff --git a/gcc/hwint.h b/gcc/hwint.h
index ebb4253e89d..94df889a0e8 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -286,6 +286,19 @@ extern HOST_WIDE_INT mul_hwi (HOST_WIDE_INT,
HOST_WIDE_INT);
extern HOST_WIDE_INT least_common_multiple (HOST_WIDE_INT, HOST_WIDE_INT);
extern unsigned HOST_WIDE_INT reflect_hwi (unsigned HOST_WIDE_INT, unsigned);
+/* Calculate CRC for a given initial CRC, DATA, POLYNOMIAL,
+ CRC_SIZE in bits and DATA_SIZE in bits. */
+extern unsigned HOST_WIDE_INT
+calculate_crc (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, unsigned short, unsigned short);
+
+/* Calculate reversed CRC for a given initial CRC, DATA, POLYNOMIAL,
+ CRC_SIZE in bits and DATA_SIZE in bits. */
+extern unsigned HOST_WIDE_INT
+calculate_reversed_crc (unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, unsigned short,
+ unsigned short);
+
/* Like ctz_hwi, except 0 when x == 0. */
inline int
--
2.54.0