diff options
author | Richard Henderson <richard.henderson@linaro.org> | 2018-10-31 09:29:29 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2018-10-31 02:29:29 -0700 |
commit | 77f33f44baf24c22848197aa80962c003dd7b3e2 (patch) | |
tree | a1fc76d6ee8e85ab16d6ba4a95070461a6e27c8f /gcc/config/aarch64/atomics.md | |
parent | 187cea947e54d08eaed2587edeb49a5cc1fe8d6a (diff) | |
download | gcc-77f33f44baf24c22848197aa80962c003dd7b3e2.zip gcc-77f33f44baf24c22848197aa80962c003dd7b3e2.tar.gz gcc-77f33f44baf24c22848197aa80962c003dd7b3e2.tar.bz2 |
aarch64: Simplify LSE cas generation
The cas insn is a single insn, and if expanded properly need not
be split after reload. Use the proper inputs for the insn.
* config/aarch64/aarch64.c (aarch64_expand_compare_and_swap):
Force oldval into the rval register for TARGET_LSE; emit the compare
during initial expansion so that it may be deleted if unused.
(aarch64_gen_atomic_cas): Remove.
* config/aarch64/atomics.md (@aarch64_compare_and_swap<SHORT>_lse):
Change =&r to +r for operand 0; use match_dup for operand 2;
remove is_weak and mod_f operands as unused. Drop the split
and merge with...
(@aarch64_atomic_cas<SHORT>): ... this pattern's output; remove.
(@aarch64_compare_and_swap<GPI>_lse): Similarly.
(@aarch64_atomic_cas<GPI>): Similarly.
From-SVN: r265656
Diffstat (limited to 'gcc/config/aarch64/atomics.md')
-rw-r--r-- | gcc/config/aarch64/atomics.md | 121 |
1 files changed, 33 insertions, 88 deletions
diff --git a/gcc/config/aarch64/atomics.md b/gcc/config/aarch64/atomics.md index bba8e9e..2266085 100644 --- a/gcc/config/aarch64/atomics.md +++ b/gcc/config/aarch64/atomics.md @@ -85,56 +85,50 @@ } ) -(define_insn_and_split "@aarch64_compare_and_swap<mode>_lse" - [(set (reg:CC CC_REGNUM) ;; bool out - (unspec_volatile:CC [(const_int 0)] UNSPECV_ATOMIC_CMPSW)) - (set (match_operand:SI 0 "register_operand" "=&r") ;; val out +(define_insn "@aarch64_compare_and_swap<mode>_lse" + [(set (match_operand:SI 0 "register_operand" "+r") ;; val out (zero_extend:SI - (match_operand:SHORT 1 "aarch64_sync_memory_operand" "+Q"))) ;; memory + (match_operand:SHORT 1 "aarch64_sync_memory_operand" "+Q"))) ;; memory (set (match_dup 1) (unspec_volatile:SHORT - [(match_operand:SI 2 "aarch64_plus_operand" "rI") ;; expected - (match_operand:SHORT 3 "aarch64_reg_or_zero" "rZ") ;; desired - (match_operand:SI 4 "const_int_operand") ;; is_weak - (match_operand:SI 5 "const_int_operand") ;; mod_s - (match_operand:SI 6 "const_int_operand")] ;; mod_f + [(match_dup 0) ;; expected + (match_operand:SHORT 2 "aarch64_reg_or_zero" "rZ") ;; desired + (match_operand:SI 3 "const_int_operand")] ;; mod_s UNSPECV_ATOMIC_CMPSW))] "TARGET_LSE" - "#" - "&& reload_completed" - [(const_int 0)] - { - aarch64_gen_atomic_cas (operands[0], operands[1], - operands[2], operands[3], - operands[5]); - DONE; - } -) +{ + enum memmodel model = memmodel_from_int (INTVAL (operands[3])); + if (is_mm_relaxed (model)) + return "cas<atomic_sfx>\t%<w>0, %<w>2, %1"; + else if (is_mm_acquire (model) || is_mm_consume (model)) + return "casa<atomic_sfx>\t%<w>0, %<w>2, %1"; + else if (is_mm_release (model)) + return "casl<atomic_sfx>\t%<w>0, %<w>2, %1"; + else + return "casal<atomic_sfx>\t%<w>0, %<w>2, %1"; +}) -(define_insn_and_split "@aarch64_compare_and_swap<mode>_lse" - [(set (reg:CC CC_REGNUM) ;; bool out - (unspec_volatile:CC [(const_int 0)] UNSPECV_ATOMIC_CMPSW)) - (set (match_operand:GPI 0 "register_operand" "=&r") ;; val out +(define_insn "@aarch64_compare_and_swap<mode>_lse" + [(set (match_operand:GPI 0 "register_operand" "+r") ;; val out (match_operand:GPI 1 "aarch64_sync_memory_operand" "+Q")) ;; memory (set (match_dup 1) (unspec_volatile:GPI - [(match_operand:GPI 2 "aarch64_plus_operand" "rI") ;; expect - (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ") ;; desired - (match_operand:SI 4 "const_int_operand") ;; is_weak - (match_operand:SI 5 "const_int_operand") ;; mod_s - (match_operand:SI 6 "const_int_operand")] ;; mod_f + [(match_dup 0) ;; expected + (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ") ;; desired + (match_operand:SI 3 "const_int_operand")] ;; mod_s UNSPECV_ATOMIC_CMPSW))] "TARGET_LSE" - "#" - "&& reload_completed" - [(const_int 0)] - { - aarch64_gen_atomic_cas (operands[0], operands[1], - operands[2], operands[3], - operands[5]); - DONE; - } -) +{ + enum memmodel model = memmodel_from_int (INTVAL (operands[3])); + if (is_mm_relaxed (model)) + return "cas<atomic_sfx>\t%<w>0, %<w>2, %1"; + else if (is_mm_acquire (model) || is_mm_consume (model)) + return "casa<atomic_sfx>\t%<w>0, %<w>2, %1"; + else if (is_mm_release (model)) + return "casl<atomic_sfx>\t%<w>0, %<w>2, %1"; + else + return "casal<atomic_sfx>\t%<w>0, %<w>2, %1"; +}) (define_expand "atomic_exchange<mode>" [(match_operand:ALLI 0 "register_operand" "") @@ -610,55 +604,6 @@ return "swpal<atomic_sfx>\t%<w>2, %<w>0, %1"; }) -;; Atomic compare-and-swap: HI and smaller modes. - -(define_insn "@aarch64_atomic_cas<mode>" - [(set (match_operand:SI 0 "register_operand" "+&r") ;; out - (zero_extend:SI - (match_operand:SHORT 1 "aarch64_sync_memory_operand" "+Q"))) ;; memory. - (set (match_dup 1) - (unspec_volatile:SHORT - [(match_dup 0) - (match_operand:SHORT 2 "aarch64_reg_or_zero" "rZ") ;; value. - (match_operand:SI 3 "const_int_operand" "")] ;; model. - UNSPECV_ATOMIC_CAS))] - "TARGET_LSE && reload_completed" -{ - enum memmodel model = memmodel_from_int (INTVAL (operands[3])); - if (is_mm_relaxed (model)) - return "cas<atomic_sfx>\t%<w>0, %<w>2, %1"; - else if (is_mm_acquire (model) || is_mm_consume (model)) - return "casa<atomic_sfx>\t%<w>0, %<w>2, %1"; - else if (is_mm_release (model)) - return "casl<atomic_sfx>\t%<w>0, %<w>2, %1"; - else - return "casal<atomic_sfx>\t%<w>0, %<w>2, %1"; -}) - -;; Atomic compare-and-swap: SI and larger modes. - -(define_insn "@aarch64_atomic_cas<mode>" - [(set (match_operand:GPI 0 "register_operand" "+&r") ;; out - (match_operand:GPI 1 "aarch64_sync_memory_operand" "+Q")) ;; memory. - (set (match_dup 1) - (unspec_volatile:GPI - [(match_dup 0) - (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ") ;; value. - (match_operand:SI 3 "const_int_operand" "")] ;; model. - UNSPECV_ATOMIC_CAS))] - "TARGET_LSE && reload_completed" -{ - enum memmodel model = memmodel_from_int (INTVAL (operands[3])); - if (is_mm_relaxed (model)) - return "cas<atomic_sfx>\t%<w>0, %<w>2, %1"; - else if (is_mm_acquire (model) || is_mm_consume (model)) - return "casa<atomic_sfx>\t%<w>0, %<w>2, %1"; - else if (is_mm_release (model)) - return "casl<atomic_sfx>\t%<w>0, %<w>2, %1"; - else - return "casal<atomic_sfx>\t%<w>0, %<w>2, %1"; -}) - ;; Atomic load-op: Load data, operate, store result, keep data. (define_insn "@aarch64_atomic_load<atomic_ldop><mode>" |