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
This commit is contained in:
parent
260eedb901
commit
8f5603d363
@ -1,5 +1,14 @@
|
||||
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>"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user