]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
i386: Introduce crc_rev<mode>si4 expanders [PR120719]
authorUros Bizjak <ubizjak@gmail.com>
Thu, 26 Jun 2025 12:13:01 +0000 (14:13 +0200)
committerUros Bizjak <ubizjak@gmail.com>
Thu, 26 Jun 2025 13:50:50 +0000 (15:50 +0200)
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.

gcc/config/i386/i386.md
gcc/testsuite/gcc.target/i386/crc-builtin-crc32.c [new file with mode: 0644]

index 41a86544bbf7c91a43dbd3adc1166a3bc52e1ca8..adff2af45631f32bc4aaf2f630cc0cce540fed43 100644 (file)
    (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 (file)
index 0000000..0b4ff97
--- /dev/null
@@ -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 } } */