https://gcc.gnu.org/g:4af2ba647dc7e4cc79a64cf8f2407a6ee70ffdde
commit 4af2ba647dc7e4cc79a64cf8f2407a6ee70ffdde Author: Jeff Law <j...@ventanamicro.com> Date: Mon Nov 11 12:56:07 2024 -0700 Patch #5 from Mariam (x86 support) Diff: --- gcc/config/i386/i386-protos.h | 2 + gcc/config/i386/i386.cc | 129 +++++++++++++++++++++ gcc/config/i386/i386.md | 59 ++++++++++ gcc/testsuite/gcc.target/i386/crc-1-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-10-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-12-pclmul.c | 9 ++ gcc/testsuite/gcc.target/i386/crc-13-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-14-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-17-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-18-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-21-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-22-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-23-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-4-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-5-pclmul.c | 9 ++ gcc/testsuite/gcc.target/i386/crc-6-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-7-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-8-pclmul.c | 8 ++ gcc/testsuite/gcc.target/i386/crc-9-pclmul.c | 8 ++ .../gcc.target/i386/crc-CCIT-data16-pclmul.c | 9 ++ .../gcc.target/i386/crc-CCIT-data8-pclmul.c | 9 ++ .../i386/crc-coremark-16bitdata-pclmul.c | 9 ++ gcc/testsuite/gcc.target/i386/crc-crc32-data16.c | 53 +++++++++ gcc/testsuite/gcc.target/i386/crc-crc32-data32.c | 53 +++++++++ gcc/testsuite/gcc.target/i386/crc-crc32-data8.c | 53 +++++++++ 25 files changed, 506 insertions(+) diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 78e72c50c6dd..e954caec644e 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -307,6 +307,8 @@ extern bool ix86_expand_vector_init_duplicate (bool, machine_mode, rtx, extern bool ix86_expand_vector_init_one_nonzero (bool, machine_mode, rtx, rtx, int); extern bool ix86_extract_perm_from_pool_constant (int*, rtx); +extern void ix86_expand_crc_using_pclmul (rtx *); +extern void ix86_expand_reversed_crc_using_pclmul (rtx *); /* In i386-c.cc */ extern void ix86_target_macros (void); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index b4d11dff4ee5..0b81bba14627 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -26670,6 +26670,135 @@ ix86_run_selftests (void) } // namespace selftest +/* Generate assembly to calculate CRC using pclmulqdq instruction. + OPERANDS[1] is input CRC, + OPERANDS[2] is data (message), + OPERANDS[3] is the polynomial without the leading 1. */ + +void +ix86_expand_crc_using_pclmul (rtx *operands) +{ +/* Check and keep arguments. */ + gcc_assert (!CONST_INT_P (operands[0])); + gcc_assert (CONST_INT_P (operands[3])); + rtx crc = operands[1]; + rtx data = operands[2]; + unsigned HOST_WIDE_INT crc_size = GET_MODE_BITSIZE (GET_MODE (operands[0])); + gcc_assert (crc_size <= 32); + unsigned HOST_WIDE_INT data_size = GET_MODE_BITSIZE (GET_MODE (data)); + unsigned HOST_WIDE_INT DImode_size = GET_MODE_BITSIZE (DImode); + + /* Calculate the quotient. */ + unsigned HOST_WIDE_INT + q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]), crc_size); + + if (crc_size > data_size) + crc = expand_shift (RSHIFT_EXPR, DImode, crc, crc_size - data_size, + NULL_RTX, 1); + + /* Keep the quotient in V2DImode. */ + rtx q_v2di = gen_reg_rtx (V2DImode); + rtx quotient = gen_reg_rtx (DImode); + convert_move (quotient, gen_int_mode (q, DImode), 0); + emit_insn (gen_vec_concatv2di (q_v2di, quotient, const0_rtx)); + + /* crc ^ data and keep in V2DImode. */ + rtx cd_xor = expand_binop (DImode, xor_optab, crc, data, NULL_RTX, 1, + OPTAB_WIDEN); + rtx res = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_concatv2di (res, cd_xor, const0_rtx)); + /* Perform carry-less multiplication. */ + emit_insn (gen_pclmulqdq (res, res, q_v2di, gen_int_mode (0, DImode))); + + res = expand_shift (RSHIFT_EXPR, V2DImode, res, crc_size, NULL_RTX, 0); + + /* Keep the polynomial in V2DImode. */ + rtx polynomial = gen_reg_rtx (DImode); + convert_move (polynomial, operands[3], 0); + rtx p_v2di = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_concatv2di (p_v2di, polynomial, const0_rtx)); + + /* Perform carry-less multiplication and get low part. */ + emit_insn (gen_pclmulqdq (res, res, p_v2di, gen_int_mode (0, DImode))); + rtx crc_part = gen_reg_rtx (DImode); + emit_insn (gen_vec_extractv2didi (crc_part, res, const0_rtx)); + + if (crc_size > data_size) + { + rtx shift = expand_shift (LSHIFT_EXPR, DImode, operands[1], data_size, + NULL_RTX, 1); + crc_part = expand_binop (DImode, xor_optab, crc_part, shift, NULL_RTX, 1, + OPTAB_DIRECT); + } + /* Zero upper bits beyond crc_size. */ + res = expand_shift (RSHIFT_EXPR, DImode, crc_part, DImode_size - crc_size, + NULL_RTX, 1); + res = expand_shift (LSHIFT_EXPR, DImode, crc_part, DImode_size - crc_size, + NULL_RTX, 0); + emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), crc_part)); +} + +/* Generate assembly to calculate reversed CRC using pclmulqdq instruction. + OPERANDS[1] is input CRC, + OPERANDS[2] is data (message), + OPERANDS[3] is the polynomial without the leading 1. */ + +void +ix86_expand_reversed_crc_using_pclmul (rtx *operands) +{ + /* Check and keep arguments. */ + gcc_assert (!CONST_INT_P (operands[0])); + gcc_assert (CONST_INT_P (operands[3])); + rtx crc = operands[1]; + rtx data = operands[2]; + unsigned HOST_WIDE_INT crc_size = GET_MODE_BITSIZE (GET_MODE (operands[0])); + gcc_assert (crc_size <= 32); + unsigned HOST_WIDE_INT data_size = GET_MODE_BITSIZE (GET_MODE (data)); + + /* Calculate the quotient. */ + unsigned HOST_WIDE_INT + q = gf2n_poly_long_div_quotient (UINTVAL (operands[3]), crc_size); + + /* Reflect the calculated quotient. */ + q = reflect_hwi (q, crc_size + 1); + rtx q_v2di = gen_reg_rtx (V2DImode); + rtx quotient = gen_reg_rtx (DImode); + convert_move (quotient, gen_int_mode (q, DImode), 0); + emit_insn (gen_vec_concatv2di (q_v2di, quotient, const0_rtx)); + + /* crc ^ data and keep in V2DImode. */ + rtx cd_xor = expand_binop (DImode, xor_optab, crc, data, NULL_RTX, 1, + OPTAB_WIDEN); + + /* Perform carry-less multiplication. */ + rtx res = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_concatv2di (res, cd_xor, const0_rtx)); + emit_insn (gen_pclmulqdq (res, res, q_v2di, gen_int_mode (0, DImode))); + + res = expand_shift (LSHIFT_EXPR, V2DImode, res, 64 - data_size, NULL_RTX, 0); + + /* Reflect the polynomial and keep in V2DImode. */ + unsigned HOST_WIDE_INT reflected_op3 = reflect_hwi (UINTVAL (operands[3]), + crc_size); + rtx ref_polynomial = gen_reg_rtx (DImode); + convert_move (ref_polynomial, gen_int_mode (reflected_op3 << 1, DImode), 0); + rtx p_v2di = gen_reg_rtx (V2DImode); + emit_insn (gen_vec_concatv2di (p_v2di, ref_polynomial, const0_rtx)); + + /* Perform carry-less multiplication and get high part. */ + emit_insn (gen_pclmulqdq (res, res, p_v2di, gen_int_mode (0, DImode))); + rtx res_high = gen_reg_rtx (DImode); + emit_insn (gen_vec_extractv2didi (res_high, res, const1_rtx)); + + if (crc_size > data_size) + { + rtx shift = expand_shift (RSHIFT_EXPR, DImode, crc, data_size, + NULL_RTX, 1); + res_high = expand_binop (DImode, xor_optab, res_high, shift, NULL_RTX, 1, + OPTAB_DIRECT); + } + emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), res_high)); +} #endif /* CHECKING_P */ static const scoped_attribute_specs *const ix86_attribute_table[] = diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 1c1bf659fc25..51a6e10d1bb2 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -191,6 +191,10 @@ ;; For CRC32 support UNSPEC_CRC32 + ;; For CRC support + UNSPEC_CRC + UNSPEC_CRC_REV + ;; For LZCNT suppoprt UNSPEC_LZCNT @@ -28699,6 +28703,61 @@ (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) + +;; Same as SWI124. Added for different combinations. +(define_mode_iterator SWI124dup [QI HI SI]) + +;; CRC 8, 16, 32 for TARGET_64 +(define_expand "crc<SWI124dup:mode><SWI124:mode>4" + ;; return value (calculated CRC) + [(set (match_operand:SWI124 0 "register_operand" "=r") + ;; initial CRC + (unspec:SWI124 [(match_operand:SWI124 1 "register_operand" "r") + ;; data + (match_operand:SWI124dup 2 "register_operand" "r") + ;; polynomial without leading 1 + (match_operand:SWI124 3)] + UNSPEC_CRC))] + /* The case when data's size is bigger than CRC's size is not supported. */ + "TARGET_PCLMUL && TARGET_64BIT && <SWI124:MODE>mode >= <SWI124dup:MODE>mode" +{ + ix86_expand_crc_using_pclmul (operands); + DONE; +}) + +;; Reversed CRC 8, 16, 32 for TARGET_64 +(define_expand "crc_rev<SWI124dup:mode><SWI124:mode>4" + ;; return value (calculated CRC) + [(set (match_operand:SWI124 0 "register_operand" "=r") + ;; initial CRC + (unspec:SWI124 [(match_operand:SWI124 1 "register_operand" "r") + ;; data + (match_operand:SWI124dup 2 "register_operand" "r") + ;; polynomial without leading 1 + (match_operand:SWI124 3)] + UNSPEC_CRC_REV))] + /* The case when data's size is bigger than CRC's size is not supported. */ + "((TARGET_PCLMUL && TARGET_64BIT) || TARGET_CRC32) + && <SWI124:MODE>mode >= <SWI124dup:MODE>mode" +{ /* If it is iSCSI polynomial (0x1EDC6F41), generate crc32 instruction. */ + if (TARGET_CRC32 && INTVAL (operands[3]) == 517762881) + { + rtx crc_part = gen_reg_rtx (SImode); + rtx crc = operands[1]; + rtx data = operands[2]; + emit_insn (gen_sse4_2_crc32<SWI124dup:mode> (crc_part, crc, data)); + emit_move_insn (operands[0], + gen_lowpart (GET_MODE (operands[0]), crc_part)); + } + else if (TARGET_PCLMUL && TARGET_64BIT) + ix86_expand_reversed_crc_using_pclmul (operands); + else + expand_reversed_crc_table_based (operands[0], operands[1], operands[2], + operands[3], GET_MODE (operands[2]), + 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-1-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-1-pclmul.c new file mode 100644 index 000000000000..21edf417f0c7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-1-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */ + +#include "../../gcc.dg/torture/crc-1.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c new file mode 100644 index 000000000000..39bfd386d9c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-10-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-10.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-12-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-12-pclmul.c new file mode 100644 index 000000000000..1ac9a6bf56d0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-12-pclmul.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc -fdisable-tree-phiopt2 -fdisable-tree-phiopt3" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include "../../gcc.dg/torture/crc-12.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-13-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-13-pclmul.c new file mode 100644 index 000000000000..c290539fad3f --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-13-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-13.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-14-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-14-pclmul.c new file mode 100644 index 000000000000..cc62ee471c7a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-14-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-14.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-17-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-17-pclmul.c new file mode 100644 index 000000000000..660bff55e1b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-17-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-17.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-18-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-18-pclmul.c new file mode 100644 index 000000000000..e54392b32a97 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-18-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-18.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-21-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-21-pclmul.c new file mode 100644 index 000000000000..4db1504cd491 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-21-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-21.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-22-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-22-pclmul.c new file mode 100644 index 000000000000..d0f27d960697 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-22-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-22.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-23-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-23-pclmul.c new file mode 100644 index 000000000000..666f36205973 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-23-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-23.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-4-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-4-pclmul.c new file mode 100644 index 000000000000..398ecaa4aba9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-4-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-4.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-5-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-5-pclmul.c new file mode 100644 index 000000000000..b80368e81bc4 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-5-pclmul.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -w -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include "../../gcc.dg/torture/crc-5.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c new file mode 100644 index 000000000000..20b851e35969 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-6-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-6.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c new file mode 100644 index 000000000000..3e5cc75338ec --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-7-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-7.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-8-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-8-pclmul.c new file mode 100644 index 000000000000..4b1145553fce --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-8-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-8.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-9-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-9-pclmul.c new file mode 100644 index 000000000000..204d6c84d474 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-9-pclmul.c @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ + +#include "../../gcc.dg/torture/crc-9.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c new file mode 100644 index 000000000000..ca7281208584 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-CCIT-data16-pclmul.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include "../../gcc.dg/torture/crc-CCIT-data16.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c new file mode 100644 index 000000000000..816e0561d8f9 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-CCIT-data8-pclmul.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto" } } */ + +#include "../../gcc.dg/torture/crc-CCIT-data8.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c b/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c new file mode 100644 index 000000000000..817d960b0aa0 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-coremark-16bitdata-pclmul.c @@ -0,0 +1,9 @@ +/* { dg-do run } */ +/* { dg-options "-w -mpclmul -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include "../../gcc.dg/torture/crc-coremark16-data16.c" + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "pclmulqdq" "dfinish"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c b/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c new file mode 100644 index 000000000000..49ab5f31ef05 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data16.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include <stdint.h> +#include <stdlib.h> + +__attribute__ ((noinline,optimize(0))) +uint32_t _crc32_O0 (uint32_t crc, uint16_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 8; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +uint32_t _crc32 (uint32_t crc, uint16_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 8; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +int main () +{ + uint32_t crc = 0x0D800D80; + for (uint16_t i = 0; i < 0xffff; i++) + { + uint32_t res1 = _crc32_O0 (crc, i); + uint32_t res2 = _crc32 (crc, i); + if (res1 != res2) + abort (); + crc = res1; + } +} + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "UNSPEC_CRC32" "dfinish"} } */ +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c b/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c new file mode 100644 index 000000000000..08d6c193a777 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data32.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include <stdint.h> +#include <stdlib.h> + +__attribute__ ((noinline,optimize(0))) +uint32_t _crc32_O0 (uint32_t crc, uint32_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 32; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +uint32_t _crc32 (uint32_t crc, uint32_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 32; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +int main () +{ + uint32_t crc = 0x0D800D80; + for (uint8_t i = 0; i < 0xff; i++) + { + uint32_t res1 = _crc32_O0 (crc, i); + uint32_t res2 = _crc32 (crc, i); + if (res1 != res2) + abort (); + crc = res1; + } +} + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "UNSPEC_CRC32" "dfinish"} } */ +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */ diff --git a/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c b/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c new file mode 100644 index 000000000000..7a76b27fd286 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/crc-crc32-data8.c @@ -0,0 +1,53 @@ +/* { dg-do run } */ +/* { dg-options "-mcrc32 -O2 -fdump-rtl-dfinish -fdump-tree-crc" } */ +/* { dg-skip-if "" { *-*-* } { "-flto"} } */ + +#include <stdint.h> +#include <stdlib.h> + +__attribute__ ((noinline,optimize(0))) +uint32_t _crc32_O0 (uint32_t crc, uint8_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 8; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +uint32_t _crc32 (uint32_t crc, uint8_t data) { + int i; + crc = crc ^ data; + + for (i = 0; i < 8; i++) { + if (crc & 1) + crc = (crc >> 1) ^ 0x82F63B78; + else + crc = (crc >> 1); + } + + return crc; +} + +int main () +{ + uint32_t crc = 0x0D800D80; + for (uint8_t i = 0; i < 0xff; i++) + { + uint32_t res1 = _crc32_O0 (crc, i); + uint32_t res2 = _crc32 (crc, i); + if (res1 != res2) + abort (); + crc = res1; + } +} + +/* { dg-final { scan-tree-dump "calculates CRC!" "crc"} } */ +/* { dg-final { scan-tree-dump-times "Couldn't generate faster CRC code." 0 "crc"} } */ +/* { dg-final { scan-rtl-dump "UNSPEC_CRC32" "dfinish"} } */ +/* { dg-final { scan-rtl-dump-times "pclmulqdq" 0 "dfinish"} } */