summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariam Arutunian <mariamarutunian@gmail.com>2023-03-17 18:04:45 +0400
committerJeff Law <jlaw@ventanamicro>2023-03-21 09:03:22 -0600
commitacd5ecb0d9a7a8d130e85cffda4963b21c3e2442 (patch)
tree8968773a129246f67f1b4fe717a61a4a9c320660
parent8e5fe469f73d4496cfbad07f8d5f922ca50ec4bb (diff)
downloadgcc-acd5ecb0d9a7a8d130e85cffda4963b21c3e2442.tar.gz
Changes in CRC code generation v6:
- Corrected expand_crc_table_based to work on crc-2-diff-size.c test. - Added check for clmul case in gcc/simplify-rtx.cc. - Added some functions in riscv.cc for reversed CRC. Changes in testsuit: - Added crc-2-diff-size.c test
-rw-r--r--gcc/config/riscv/bitmanip.md8
-rw-r--r--gcc/config/riscv/riscv.cc66
-rw-r--r--gcc/simplify-rtx.cc1
-rw-r--r--gcc/testsuite/gcc.dg/crc-2-diff-size.c40
4 files changed, 102 insertions, 13 deletions
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index 5b6a5238a01..2a9202d60d2 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -659,7 +659,7 @@
(define_insn "clmul<mode>3"
[(set (match_operand:X 0 "register_operand" "=r")
(clmul:X (match_operand:X 1 "register_operand" "r")
-(match_operand:X 2 "arith_operand" "r")))]
+(match_operand:X 2 "register_operand" "r")))]
"TARGET_ZBC"
"clmul\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
@@ -668,7 +668,7 @@
(define_insn "clmulh<mode>3"
[(set (match_operand:X 0 "register_operand" "=r")
(plus:X (match_operand:X 1 "register_operand" " r")
-(match_operand:X 2 "arith_operand" " r")))]
+(match_operand:X 2 "register_operand" "r")))]
"TARGET_ZBC"
"clmulh\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
@@ -677,7 +677,7 @@
(define_insn "clmulr<mode>3"
[(set (match_operand:X 0 "register_operand" "=r")
(clmulr:X (match_operand:X 1 "register_operand" "r")
-(match_operand:X 2 "arith_operand" "r")))]
+(match_operand:X 2 "register_operand" "r")))]
"TARGET_ZBC"
"clmulr\t%0,%1,%2"
[(set_attr "type" "bitmanip")])
@@ -691,7 +691,7 @@
if (TARGET_ZBC)
{
// Instruction sequence from slides. Sizes need to be fixed.
- rtx a0 = operands[0], a1 = operands[1];
+ rtx a0 = operands[1], a1 = operands[2];
unsigned HOST_WIDE_INT
q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]));
rtx t0 = gen_rtx_CONST (SImode, GEN_INT (q));
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index b78b9903033..842fe3f7902 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -6951,21 +6951,32 @@ gf2n_poly_long_div_quotient (unsigned HOST_WIDE_INT polynomial)
return quotient;
}
+/* Calculates reciprocal CRC for initial CRC and given polynomial. */
+static uint16_t
+generate_crc_reciprocal (uint16_t crc,
+ uint16_t polynomial)
+{
+ for (int bits = 16; bits > 0; --bits)
+ {
+ int tmp = crc & 1;
+ crc >>= 1;
+ if (tmp)
+ crc ^= polynomial;
+ }
+ return crc;
+}
+
/* Calculates CRC for initial CRC and given polynomial. */
static uint16_t
generate_crc (uint16_t crc,
- uint16_t polynomial)
+ uint16_t polynomial)
{
for (int bits = 16; bits > 0; --bits)
{
if (crc & 0x8000)
- {
- crc = (crc << 1) ^ polynomial;
- }
+ crc = (crc << 1) ^ polynomial;
else
- {
- crc <<= 1;
- }
+ crc <<= 1;
}
return crc;
@@ -7005,12 +7016,25 @@ generate_crc16_table (uint16_t polynom)
return lab;
}
+void reflect (rtx op1, machine_mode mode)
+{
+ // Reflect the bits
+ op1 = gen_rtx_BSWAP (mode, op1);
+
+// Adjust the position of the reflected bits
+ if (mode != Pmode)
+ op1 = gen_rtx_SUBREG (Pmode, op1, 0);
+
+// Shift the reflected bits to the least significant end
+ rtx shift_amt = gen_rtx_CONST_INT (Pmode, 8);
+ op1 = gen_rtx_LSHIFTRT (Pmode, op1, shift_amt);
+}
+
/* Generate table based CRC code. */
void
-expand_crc_table_based (rtx *operands, machine_mode data_mode)
+expand_crc_table_based_reflected (rtx *operands, machine_mode data_mode)
{
machine_mode mode = GET_MODE (operands[0]);
-
rtx in = force_reg (mode, gen_rtx_XOR (mode, operands[1], operands[2]));
rtx ix = gen_rtx_AND (mode, in, GEN_INT (GET_MODE_MASK (data_mode)));
if (mode != Pmode)
@@ -7027,6 +7051,30 @@ expand_crc_table_based (rtx *operands, machine_mode data_mode)
riscv_emit_move (operands[0], gen_rtx_SUBREG (mode, crc, 0));
}
+/* Generate table based CRC code. */
+void
+expand_crc_table_based (rtx *operands, machine_mode data_mode)
+{
+ machine_mode mode = GET_MODE (operands[0]);
+ rtx op1 = gen_rtx_ASHIFTRT (mode, operands[1],
+ GEN_INT (8));
+ rtx in = force_reg (mode, gen_rtx_XOR (mode, op1, operands[2]));
+ rtx ix = gen_rtx_AND (mode, in, GEN_INT (GET_MODE_MASK (data_mode)));
+ if (mode != Pmode)
+ ix = gen_rtx_SUBREG (Pmode, ix, 0);
+ ix = gen_rtx_ASHIFT (Pmode, ix, GEN_INT (exact_log2 (GET_MODE_SIZE (mode)
+ .to_constant ())));
+ ix = force_reg (Pmode, ix);
+ rtx tab = generate_crc16_table (UINTVAL (operands[3]));
+ tab = gen_rtx_MEM (mode, gen_rtx_PLUS (Pmode, ix, tab));
+
+ rtx high = gen_rtx_ASHIFT (mode, operands[1],
+ GEN_INT (8));
+ high = force_reg (mode, gen_rtx_AND (mode, high, GEN_INT (65535)));
+ rtx crc = force_reg (mode, gen_rtx_XOR (mode, tab, high));
+ riscv_emit_move (operands[0], crc);
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
index 3b33afa2461..35dafc70d3a 100644
--- a/gcc/simplify-rtx.cc
+++ b/gcc/simplify-rtx.cc
@@ -4289,6 +4289,7 @@ simplify_ashift:
return op0;
return 0;
+ case CLMUL:
case SS_MULT:
case US_MULT:
/* Simplify x * 0 to 0, if possible. */
diff --git a/gcc/testsuite/gcc.dg/crc-2-diff-size.c b/gcc/testsuite/gcc.dg/crc-2-diff-size.c
new file mode 100644
index 00000000000..f70f787532f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/crc-2-diff-size.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-crc-details" } */
+#include <stdio.h>
+unsigned short crc16(unsigned char newByte, unsigned short crcValue) {
+ unsigned char i;
+
+ for (i = 0; i < 8; i++) {
+
+ if (((crcValue & 0x8000) >> 8) ^ (newByte & 0x80)) {
+ crcValue = (crcValue << 1) ^ 0x102;
+ } else {
+ crcValue = (crcValue << 1);
+ }
+
+ newByte <<= 1;
+ }
+
+ return crcValue;
+}
+
+int main ()
+{
+ unsigned short crc = 0;
+
+ crc = crc16(0x12, crc);
+ printf("%04X\n", crc); // 1224
+
+ crc = crc16(0x34, crc);
+ printf("%04X\n", crc); // 024C
+
+ crc = crc16(0x35, crc);
+ printf("%04X\n", crc); // 7B6E
+
+}
+
+/* { dg-final { scan-tree-dump "crc16 function maybe calculates CRC and returns it." "crc"} } */
+/* { dg-final { scan-tree-dump "Return size is 16" "crc"} } */
+/* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */
+/* { dg-final { scan-tree-dump "Bit forward" "crc"} } */
+/* { dg-final { scan-tree-dump "crc16 function calculates CRC!" "crc"} } */