]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Changes in CRC code generation v6:
authorMariam Arutunian <mariamarutunian@gmail.com>
Fri, 17 Mar 2023 14:04:45 +0000 (18:04 +0400)
committerJeff Law <jlaw@ventanamicro>
Tue, 21 Mar 2023 15:03:22 +0000 (09:03 -0600)
    - 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

gcc/config/riscv/bitmanip.md
gcc/config/riscv/riscv.cc
gcc/simplify-rtx.cc
gcc/testsuite/gcc.dg/crc-2-diff-size.c [new file with mode: 0644]

index 5b6a5238a017f1bb785affe910fa32ac93f62391..2a9202d60d2635d68510371f1416911acc8ad515 100644 (file)
 (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")])
 (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")])
 (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")])
 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));
index b78b99030335f98ea32282978ee100b3e53464c5..842fe3f7902e79063702c64cc5a1fa39e59d744b 100644 (file)
@@ -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"
index 3b33afa24617f3185872ddc43284e4c9cd073510..35dafc70d3a571be7edf4f1ca2ff5eec625a78f0 100644 (file)
@@ -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 (file)
index 0000000..f70f787
--- /dev/null
@@ -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"} } */