Commit 8f5603d3 by Richard Henderson Committed by Richard Henderson

aarch64: Improve swp generation

Allow zero as an input; fix constraints; avoid unnecessary split.

	* config/aarch64/aarch64.c (aarch64_emit_atomic_swap): Remove.
	(aarch64_gen_atomic_ldop): Don't call it.
	* config/aarch64/atomics.md (atomic_exchange<ALLI>):
	Use aarch64_reg_or_zero.
	(aarch64_atomic_exchange<ALLI>): Likewise.
	(aarch64_atomic_exchange<ALLI>_lse): Remove split; remove & from
	operand 0; use aarch64_reg_or_zero for input; merge ...
	(@aarch64_atomic_swp<ALLI>): ... this and remove.

From-SVN: r265659
parent 260eedb9
2018-10-31 Richard Henderson <richard.henderson@linaro.org>
* config/aarch64/aarch64.c (aarch64_emit_atomic_swap): Remove.
(aarch64_gen_atomic_ldop): Don't call it.
* config/aarch64/atomics.md (atomic_exchange<ALLI>):
Use aarch64_reg_or_zero.
(aarch64_atomic_exchange<ALLI>): Likewise.
(aarch64_atomic_exchange<ALLI>_lse): Remove split; remove & from
operand 0; use aarch64_reg_or_zero for input; merge ...
(@aarch64_atomic_swp<ALLI>): ... this and remove.
* config/aarch64/aarch64.c (aarch64_gen_compare_reg_maybe_ze): New.
(aarch64_split_compare_and_swap): Use it.
(aarch64_expand_compare_and_swap): Likewise. Remove convert_modes;
......@@ -14840,15 +14840,6 @@ aarch64_emit_bic (machine_mode mode, rtx dst, rtx s1, rtx s2, int shift)
emit_insn (gen (dst, s2, shift_rtx, s1));
}
/* Emit an atomic swap. */
static void
aarch64_emit_atomic_swap (machine_mode mode, rtx dst, rtx value,
rtx mem, rtx model)
{
emit_insn (gen_aarch64_atomic_swp (mode, dst, mem, value, model));
}
/* Emit an atomic load+operate. CODE is the operation. OUT_DATA is the
location to store the data read from memory. OUT_RESULT is the location to
store the result of the operation. MEM is the memory location to read and
......@@ -14889,10 +14880,6 @@ aarch64_gen_atomic_ldop (enum rtx_code code, rtx out_data, rtx out_result,
a SET then emit a swap instruction and finish. */
switch (code)
{
case SET:
aarch64_emit_atomic_swap (mode, out_data, src, mem, model_rtx);
return;
case MINUS:
/* Negate the value and treat it as a PLUS. */
{
......
......@@ -136,7 +136,7 @@
(define_expand "atomic_exchange<mode>"
[(match_operand:ALLI 0 "register_operand" "")
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "")
(match_operand:ALLI 2 "register_operand" "")
(match_operand:ALLI 2 "aarch64_reg_or_zero" "")
(match_operand:SI 3 "const_int_operand" "")]
""
{
......@@ -156,10 +156,10 @@
(define_insn_and_split "aarch64_atomic_exchange<mode>"
[(set (match_operand:ALLI 0 "register_operand" "=&r") ;; output
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q")) ;; memory
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q")) ;; memory
(set (match_dup 1)
(unspec_volatile:ALLI
[(match_operand:ALLI 2 "register_operand" "r") ;; input
[(match_operand:ALLI 2 "aarch64_reg_or_zero" "rZ") ;; input
(match_operand:SI 3 "const_int_operand" "")] ;; model
UNSPECV_ATOMIC_EXCHG))
(clobber (reg:CC CC_REGNUM))
......@@ -175,22 +175,25 @@
}
)
(define_insn_and_split "aarch64_atomic_exchange<mode>_lse"
[(set (match_operand:ALLI 0 "register_operand" "=&r")
(define_insn "aarch64_atomic_exchange<mode>_lse"
[(set (match_operand:ALLI 0 "register_operand" "=r")
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q"))
(set (match_dup 1)
(unspec_volatile:ALLI
[(match_operand:ALLI 2 "register_operand" "r")
[(match_operand:ALLI 2 "aarch64_reg_or_zero" "rZ")
(match_operand:SI 3 "const_int_operand" "")]
UNSPECV_ATOMIC_EXCHG))]
"TARGET_LSE"
"#"
"&& reload_completed"
[(const_int 0)]
{
aarch64_gen_atomic_ldop (SET, operands[0], NULL, operands[1],
operands[2], operands[3]);
DONE;
enum memmodel model = memmodel_from_int (INTVAL (operands[3]));
if (is_mm_relaxed (model))
return "swp<atomic_sfx>\t%<w>2, %<w>0, %1";
else if (is_mm_acquire (model) || is_mm_consume (model))
return "swpa<atomic_sfx>\t%<w>2, %<w>0, %1";
else if (is_mm_release (model))
return "swpl<atomic_sfx>\t%<w>2, %<w>0, %1";
else
return "swpal<atomic_sfx>\t%<w>2, %<w>0, %1";
}
)
......@@ -585,28 +588,6 @@
;; ARMv8.1-A LSE instructions.
;; Atomic swap with memory.
(define_insn "@aarch64_atomic_swp<mode>"
[(set (match_operand:ALLI 0 "register_operand" "+&r")
(match_operand:ALLI 1 "aarch64_sync_memory_operand" "+Q"))
(set (match_dup 1)
(unspec_volatile:ALLI
[(match_operand:ALLI 2 "register_operand" "r")
(match_operand:SI 3 "const_int_operand" "")]
UNSPECV_ATOMIC_SWP))]
"TARGET_LSE && reload_completed"
{
enum memmodel model = memmodel_from_int (INTVAL (operands[3]));
if (is_mm_relaxed (model))
return "swp<atomic_sfx>\t%<w>2, %<w>0, %1";
else if (is_mm_acquire (model) || is_mm_consume (model))
return "swpa<atomic_sfx>\t%<w>2, %<w>0, %1";
else if (is_mm_release (model))
return "swpl<atomic_sfx>\t%<w>2, %<w>0, %1";
else
return "swpal<atomic_sfx>\t%<w>2, %<w>0, %1";
})
;; Atomic load-op: Load data, operate, store result, keep data.
(define_insn "@aarch64_atomic_load<atomic_ldop><mode>"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment