Introduce crc_rev<mode>si4 expanders to generate CRC32 instruction when using
__builtin_rev_crc32_data* builtins with 0x1EDC6F41 poylnomial and -mcrc32.

    PR target/120719

gcc/ChangeLog:

    * config/i386/i386.md (crc_rev<SWI124:mode>si4): New expander.

gcc/testsuite/ChangeLog:

    * gcc.target/i386/crc-builtin-crc32.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Uros.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 41a86544bbf..adff2af4563 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -29523,6 +29523,23 @@ (define_insn "sse4_2_crc32di"
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "DI")])
 
+(define_expand "crc_rev<SWI124:mode>si4"
+  [(match_operand:SI 0 "register_operand")
+   (match_operand:SI 1 "register_operand")
+   (match_operand:SWI124 2 "nonimmediate_operand")
+   (match_operand:SI 3)]
+  "TARGET_CRC32"
+{
+  /* crc32 uses iSCSI polynomial */
+  if (INTVAL (operands[3]) == 0x1EDC6F41)
+    emit_insn (gen_sse4_2_crc32<mode> (operands[0], operands[1], operands[2]));
+  else
+    expand_reversed_crc_table_based (operands[0], operands[1], operands[2],
+                                    operands[3], <SWI124:MODE>mode,
+                                    generate_reflecting_code_standard);
+  DONE;
+})
+
 (define_insn "rdpmc"
   [(set (match_operand:DI 0 "register_operand" "=A")
        (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
diff --git a/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c 
b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c
new file mode 100644
index 00000000000..0b4ff978817
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c
@@ -0,0 +1,22 @@
+/* PR target/120719 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mcrc32" } */
+
+#include <stdint-gcc.h>
+
+int32_t rev_crc32_data8 (int8_t v)
+{
+  return __builtin_rev_crc32_data8 (0xffffffff, v, 0x1EDC6F41);
+}
+
+int32_t rev_crc32_data16 (int16_t v)
+{
+  return __builtin_rev_crc32_data16 (0xffffffff, v, 0x1EDC6F41);
+}
+
+int32_t rev_crc32_data32 (int32_t v)
+{
+  return __builtin_rev_crc32_data32 (0xffffffff, v, 0x1EDC6F41);
+} 
+
+/* { dg-final { scan-assembler-times "\tcrc32" 3 } } */

Reply via email to