aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64/atomics.md
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2018-10-31 09:29:29 +0000
committerRichard Henderson <rth@gcc.gnu.org>2018-10-31 02:29:29 -0700
commit77f33f44baf24c22848197aa80962c003dd7b3e2 (patch)
treea1fc76d6ee8e85ab16d6ba4a95070461a6e27c8f /gcc/config/aarch64/atomics.md
parent187cea947e54d08eaed2587edeb49a5cc1fe8d6a (diff)
downloadgcc-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.md121
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>"