diff options
author | Mariam Arutunian <mariamarutunian@gmail.com> | 2023-03-17 18:04:45 +0400 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro> | 2023-03-21 09:03:22 -0600 |
commit | acd5ecb0d9a7a8d130e85cffda4963b21c3e2442 (patch) | |
tree | 8968773a129246f67f1b4fe717a61a4a9c320660 | |
parent | 8e5fe469f73d4496cfbad07f8d5f922ca50ec4bb (diff) | |
download | gcc-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.md | 8 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.cc | 66 | ||||
-rw-r--r-- | gcc/simplify-rtx.cc | 1 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/crc-2-diff-size.c | 40 |
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"} } */ |