diff options
author | Wilco Dijkstra <wilco.dijkstra@arm.com> | 2022-05-18 16:06:57 +0100 |
---|---|---|
committer | Wilco Dijkstra <wdijkstr@arm.com> | 2022-05-20 15:10:38 +0100 |
commit | 48f3f27f607d3c145ed1e3ad652baac84aacdb91 (patch) | |
tree | 634988a7a0a3ca93a1c176080f168444f85723e6 /gcc/config/aarch64 | |
parent | 1be715f31605976d8e4336973d3b81c5b7cea79f (diff) | |
download | gcc-48f3f27f607d3c145ed1e3ad652baac84aacdb91.zip gcc-48f3f27f607d3c145ed1e3ad652baac84aacdb91.tar.gz gcc-48f3f27f607d3c145ed1e3ad652baac84aacdb91.tar.bz2 |
AArch64: Improve rotate patterns
Improve and generalize rotate patterns. Rotates by more than half the
bitwidth of a register are canonicalized to rotate left. Many existing
shift patterns don't handle this case correctly, so add rotate left to
the shift iterator and convert rotate left into ror during assembly
output. Add missing zero_extend patterns for shifted BIC, ORN and EON.
gcc/
* config/aarch64/aarch64.md
(and_<SHIFT:optab><mode>3_compare0): Support rotate left.
(and_<SHIFT:optab>si3_compare0_uxtw): Likewise.
(<LOGICAL:optab>_<SHIFT:optab><mode>3): Likewise.
(<LOGICAL:optab>_<SHIFT:optab>si3_uxtw): Likewise.
(one_cmpl_<optab><mode>2): Likewise.
(<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3): Likewise.
(<LOGICAL:optab>_one_cmpl_<SHIFT:optab>sidi_uxtw): New pattern.
(eor_one_cmpl_<SHIFT:optab><mode>3_alt): Support rotate left.
(eor_one_cmpl_<SHIFT:optab>sidi3_alt_ze): Likewise.
(and_one_cmpl_<SHIFT:optab><mode>3_compare0): Likewise.
(and_one_cmpl_<SHIFT:optab>si3_compare0_uxtw): Likewise.
(and_one_cmpl_<SHIFT:optab><mode>3_compare0_no_reuse): Likewise.
(and_<SHIFT:optab><mode>3nr_compare0): Likewise.
(*<optab>si3_insn_uxtw): Use SHIFT_no_rotate.
(rolsi3_insn_uxtw): New pattern.
* config/aarch64/iterators.md (SHIFT): Add rotate left.
(SHIFT_no_rotate): Add new iterator.
(SHIFT:shift): Print rotate left as ror.
(is_rotl): Add test for left rotate.
gcc/testsuite/
* gcc.target/aarch64/ror_2.c: New test.
* gcc.target/aarch64/ror_3.c: New test.
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 179 | ||||
-rw-r--r-- | gcc/config/aarch64/iterators.md | 11 |
2 files changed, 125 insertions, 65 deletions
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 2ac8d56..acec8c1 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -4549,7 +4549,11 @@ (set (match_operand:GPI 0 "register_operand" "=r") (and:GPI (SHIFT:GPI (match_dup 1) (match_dup 2)) (match_dup 3)))] "" - "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -4566,7 +4570,11 @@ (zero_extend:DI (and:SI (SHIFT:SI (match_dup 1) (match_dup 2)) (match_dup 3))))] "" - "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -4577,7 +4585,11 @@ (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) (match_operand:GPI 3 "register_operand" "r")))] "" - "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4647,17 +4659,6 @@ "operands[3] = gen_reg_rtx (<MODE>mode);" ) -(define_insn "*<optab>_rol<mode>3" - [(set (match_operand:GPI 0 "register_operand" "=r") - (LOGICAL:GPI (rotate:GPI - (match_operand:GPI 1 "register_operand" "r") - (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) - (match_operand:GPI 3 "register_operand" "r")))] - "" - "<logical>\\t%<w>0, %<w>3, %<w>1, ror #(<sizen> - %2)" - [(set_attr "type" "logic_shift_imm")] -) - ;; zero_extend versions of above (define_insn "*<LOGICAL:optab>_<SHIFT:optab>si3_uxtw" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4667,19 +4668,11 @@ (match_operand:QI 2 "aarch64_shift_imm_si" "n")) (match_operand:SI 3 "register_operand" "r"))))] "" - "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2" - [(set_attr "type" "logic_shift_imm")] -) - -(define_insn "*<optab>_rolsi3_uxtw" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (LOGICAL:SI (rotate:SI - (match_operand:SI 1 "register_operand" "r") - (match_operand:QI 2 "aarch64_shift_imm_si" "n")) - (match_operand:SI 3 "register_operand" "r"))))] - "" - "<logical>\\t%w0, %w3, %w1, ror #(32 - %2)" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4708,7 +4701,11 @@ (not:GPI (SHIFT:GPI (match_operand:GPI 1 "register_operand" "r") (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))))] "" - "mvn\\t%<w>0, %<w>1, <shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "mvn\\t%<w>0, %<w>1, <shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4815,7 +4812,28 @@ (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n"))) (match_operand:GPI 3 "register_operand" "r")))] "" - "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"; +} + [(set_attr "type" "logic_shift_imm")] +) + +;; Zero-extend version of the above. +(define_insn "<LOGICAL:optab>_one_cmpl_<SHIFT:optab>sidi_uxtw" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (LOGICAL:SI (not:SI + (SHIFT:SI + (match_operand:SI 1 "register_operand" "r") + (match_operand:QI 2 "aarch64_shift_imm_si" "n"))) + (match_operand:SI 3 "register_operand" "r"))))] + "" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "<LOGICAL:nlogical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4827,7 +4845,11 @@ (match_operand:QI 2 "aarch64_shift_imm_<mode>" "n")) (match_operand:GPI 3 "register_operand" "r"))))] "" - "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "eon\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4841,7 +4863,11 @@ (match_operand:QI 2 "aarch64_shift_imm_si" "n")) (match_operand:SI 3 "register_operand" "r")))))] "" - "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "eon\\t%w0, %w3, %w1, <SHIFT:shift> %2"; +} [(set_attr "type" "logic_shift_imm")] ) @@ -4859,7 +4885,11 @@ (SHIFT:GPI (match_dup 1) (match_dup 2))) (match_dup 3)))] "" - "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -4878,7 +4908,11 @@ (not:SI (SHIFT:SI (match_dup 1) (match_dup 2))) (match_dup 3))))] "" - "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2" +{ + if (<SHIFT:is_rotl>) + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -4892,7 +4926,11 @@ (match_operand:GPI 2 "register_operand" "r")) (const_int 0)))] "" - "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1" +{ + if (<SHIFT:is_rotl>) + operands[1] = GEN_INT (<sizen> - UINTVAL (operands[1])); + return "bics\\t<w>zr, %<w>2, %<w>0, <SHIFT:shift> %1"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -5066,7 +5104,11 @@ (match_operand:GPI 2 "register_operand" "r")) (const_int 0)))] "" - "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1" +{ + if (<SHIFT:is_rotl>) + operands[1] = GEN_INT (<sizen> - UINTVAL (operands[1])); + return "tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"; +} [(set_attr "type" "logics_shift_imm")] ) @@ -5467,10 +5509,22 @@ [(set_attr "type" "rotate_imm,shift_reg")] ) -;; zero_extend version of above +(define_insn "*rol<mode>3_insn" + [(set (match_operand:GPI 0 "register_operand" "=r") + (rotate:GPI (match_operand:GPI 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n")))] + "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" +{ + operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2])); + return "ror\\t%<w>0, %<w>1, %3"; +} + [(set_attr "type" "rotate_imm")] +) + +;; zero_extend version of shifts (define_insn "*<optab>si3_insn_uxtw" [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (SHIFT:SI + (zero_extend:DI (SHIFT_no_rotate:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "Uss,r"))))] "" @@ -5480,6 +5534,31 @@ [(set_attr "type" "bfx,shift_reg")] ) +;; zero_extend version of rotate right +(define_insn "*rorsi3_insn_uxtw" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (rotatert:SI (match_operand:SI 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n"))))] + "UINTVAL (operands[2]) < 32" + "ror\\t%w0, %w1, %2" + [(set_attr "type" "rotate_imm")] +) + +;; zero_extend version of rotate left +(define_insn "*rolsi3_insn_uxtw" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI + (rotate:SI (match_operand:SI 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n"))))] + "UINTVAL (operands[2]) < 32" +{ + operands[2] = GEN_INT (32 - UINTVAL (operands[2])); + return "ror\\t%w0, %w1, %2"; +} + [(set_attr "type" "rotate_imm")] +) + (define_insn "*<optab><mode>3_insn" [(set (match_operand:SHORT 0 "register_operand" "=r") (ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r") @@ -5562,32 +5641,6 @@ [(set_attr "type" "rotate_imm")] ) -(define_insn "*ror<mode>3_insn" - [(set (match_operand:GPI 0 "register_operand" "=r") - (rotate:GPI (match_operand:GPI 1 "register_operand" "r") - (match_operand 2 "const_int_operand" "n")))] - "UINTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)" -{ - operands[3] = GEN_INT (<sizen> - UINTVAL (operands[2])); - return "ror\\t%<w>0, %<w>1, %3"; -} - [(set_attr "type" "rotate_imm")] -) - -;; zero_extend version of the above -(define_insn "*rorsi3_insn_uxtw" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (rotate:SI (match_operand:SI 1 "register_operand" "r") - (match_operand 2 "const_int_operand" "n"))))] - "UINTVAL (operands[2]) < 32" -{ - operands[3] = GEN_INT (32 - UINTVAL (operands[2])); - return "ror\\t%w0, %w1, %3"; -} - [(set_attr "type" "rotate_imm")] -) - (define_insn "*<ANY_EXTEND:optab><GPI:mode>_ashl<SHORT:mode>" [(set (match_operand:GPI 0 "register_operand" "=r") (ANY_EXTEND:GPI diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md index 1c10483..1be6a91 100644 --- a/gcc/config/aarch64/iterators.md +++ b/gcc/config/aarch64/iterators.md @@ -2119,7 +2119,10 @@ ;; ------------------------------------------------------------------- ;; This code iterator allows the various shifts supported on the core -(define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotatert]) +(define_code_iterator SHIFT [ashift ashiftrt lshiftrt rotatert rotate]) + +;; This code iterator allows all shifts except for rotates. +(define_code_iterator SHIFT_no_rotate [ashift ashiftrt lshiftrt]) ;; This code iterator allows the shifts supported in arithmetic instructions (define_code_iterator ASHIFT [ashift ashiftrt lshiftrt]) @@ -2249,6 +2252,7 @@ (ashiftrt "ashr") (lshiftrt "lshr") (rotatert "rotr") + (rotate "rotl") (sign_extend "extend") (zero_extend "zero_extend") (sign_extract "extv") @@ -2338,7 +2342,10 @@ ;; Similar for the instruction mnemonics (define_code_attr shift [(ashift "lsl") (ashiftrt "asr") - (lshiftrt "lsr") (rotatert "ror")]) + (lshiftrt "lsr") (rotatert "ror") (rotate "ror")]) +;; True if shift is rotate left. +(define_code_attr is_rotl [(ashift "0") (ashiftrt "0") + (lshiftrt "0") (rotatert "0") (rotate "1")]) ;; Op prefix for shift right and accumulate. (define_code_attr sra_op [(ashiftrt "s") (lshiftrt "u")]) |