Commit 28875d67 by Richard Henderson Committed by Richard Henderson

ia64: Update to atomic optabs

        * config/ia64/ia64.c (ia64_expand_atomic_op): Add model parameter.
        Generate the barrier required for the memory model.
        (rtx_needs_barrier): Handle UNSPEC_FETCHADD_REL, UNSPEC_CMPXCHG_REL.
        * config/ia64/ia64-protos.h: Update.
        * config/ia64/ia64.md (UNSPEC_FETCHADD_REL): New.
        (UNSPEC_CMPXCHG_REL): New.
        * config/ia64/sync.md (mem_thread_fence): New.
        (atomic_load<IMODE>, atomic_store<IMODE>): New.
        (atomic_compare_and_swap<IMODE>): New.
        (cmpxchg_acq_<I124MODE>, cmpxchg_acq_di): New.
        (atomic_exchange<IMODE>): New.
        (xchg_acq_<IMODE>): Rename from sync_lock_test_and_set<IMODE>.
        (atomic_<FETCHOP><IMODE>, atomic_nand<IMODE>): New.
        (atomic_fetch_<FETCHOP><IMODE>, atomic_fetch_nand<IMODE>): New.
        (atomic_<FETCHOP>_fetch<IMODE>, atomic_nand_fetch<IMODE>): New.
        (fetchadd_rel_<I48MODE>): New.
        (sync_<FETCHOP><IMODE>, sync_nand<IMODE>): Remove.
        (sync_old_<FETCHOP><IMODE>, sync_old_nand<IMODE>): Remove.
        (sync_new_<FETCHOP><IMODE>, sync_new_nand<IMODE>): Remove.
        (sync_compare_and_swap<IMODE>): Remove.
        (sync_lock_release<IMODE>): Remove.

From-SVN: r181643
parent 127e44c8
2011-11-22 Richard Henderson <rth@redhat.com> 2011-11-22 Richard Henderson <rth@redhat.com>
* config/ia64/ia64.c (ia64_expand_atomic_op): Add model parameter.
Generate the barrier required for the memory model.
(rtx_needs_barrier): Handle UNSPEC_FETCHADD_REL, UNSPEC_CMPXCHG_REL.
* config/ia64/ia64-protos.h: Update.
* config/ia64/ia64.md (UNSPEC_FETCHADD_REL): New.
(UNSPEC_CMPXCHG_REL): New.
* config/ia64/sync.md (mem_thread_fence): New.
(atomic_load<IMODE>, atomic_store<IMODE>): New.
(atomic_compare_and_swap<IMODE>): New.
(cmpxchg_acq_<I124MODE>, cmpxchg_acq_di): New.
(atomic_exchange<IMODE>): New.
(xchg_acq_<IMODE>): Rename from sync_lock_test_and_set<IMODE>.
(atomic_<FETCHOP><IMODE>, atomic_nand<IMODE>): New.
(atomic_fetch_<FETCHOP><IMODE>, atomic_fetch_nand<IMODE>): New.
(atomic_<FETCHOP>_fetch<IMODE>, atomic_nand_fetch<IMODE>): New.
(fetchadd_rel_<I48MODE>): New.
(sync_<FETCHOP><IMODE>, sync_nand<IMODE>): Remove.
(sync_old_<FETCHOP><IMODE>, sync_old_nand<IMODE>): Remove.
(sync_new_<FETCHOP><IMODE>, sync_new_nand<IMODE>): Remove.
(sync_compare_and_swap<IMODE>): Remove.
(sync_lock_release<IMODE>): Remove.
* config/ia64/ia64.md: Use define_e_enum for UNSPEC_* * config/ia64/ia64.md: Use define_e_enum for UNSPEC_*
and UNSPECV_* constants. and UNSPECV_* constants.
...@@ -47,7 +47,8 @@ extern void ia64_expand_dot_prod_v8qi (rtx[], bool); ...@@ -47,7 +47,8 @@ extern void ia64_expand_dot_prod_v8qi (rtx[], bool);
extern void ia64_expand_call (rtx, rtx, rtx, int); extern void ia64_expand_call (rtx, rtx, rtx, int);
extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int); extern void ia64_split_call (rtx, rtx, rtx, rtx, rtx, int, int);
extern void ia64_reload_gp (void); extern void ia64_reload_gp (void);
extern void ia64_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx); extern void ia64_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx,
enum memmodel);
extern HOST_WIDE_INT ia64_initial_elimination_offset (int, int); extern HOST_WIDE_INT ia64_initial_elimination_offset (int, int);
extern void ia64_expand_prologue (void); extern void ia64_expand_prologue (void);
......
...@@ -2266,7 +2266,7 @@ ia64_split_call (rtx retval, rtx addr, rtx retaddr, rtx scratch_r, ...@@ -2266,7 +2266,7 @@ ia64_split_call (rtx retval, rtx addr, rtx retaddr, rtx scratch_r,
void void
ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
rtx old_dst, rtx new_dst) rtx old_dst, rtx new_dst, enum memmodel model)
{ {
enum machine_mode mode = GET_MODE (mem); enum machine_mode mode = GET_MODE (mem);
rtx old_reg, new_reg, cmp_reg, ar_ccv, label; rtx old_reg, new_reg, cmp_reg, ar_ccv, label;
...@@ -2283,12 +2283,31 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, ...@@ -2283,12 +2283,31 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
if (!old_dst) if (!old_dst)
old_dst = gen_reg_rtx (mode); old_dst = gen_reg_rtx (mode);
switch (model)
{
case MEMMODEL_ACQ_REL:
case MEMMODEL_SEQ_CST:
emit_insn (gen_memory_barrier ()); emit_insn (gen_memory_barrier ());
/* FALLTHRU */
case MEMMODEL_RELAXED:
case MEMMODEL_ACQUIRE:
case MEMMODEL_CONSUME:
if (mode == SImode) if (mode == SImode)
icode = CODE_FOR_fetchadd_acq_si; icode = CODE_FOR_fetchadd_acq_si;
else else
icode = CODE_FOR_fetchadd_acq_di; icode = CODE_FOR_fetchadd_acq_di;
break;
case MEMMODEL_RELEASE:
if (mode == SImode)
icode = CODE_FOR_fetchadd_rel_si;
else
icode = CODE_FOR_fetchadd_rel_di;
break;
default:
gcc_unreachable ();
}
emit_insn (GEN_FCN (icode) (old_dst, mem, val)); emit_insn (GEN_FCN (icode) (old_dst, mem, val));
if (new_dst) if (new_dst)
...@@ -2302,8 +2321,12 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, ...@@ -2302,8 +2321,12 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
} }
/* Because of the volatile mem read, we get an ld.acq, which is the /* Because of the volatile mem read, we get an ld.acq, which is the
front half of the full barrier. The end half is the cmpxchg.rel. */ front half of the full barrier. The end half is the cmpxchg.rel.
gcc_assert (MEM_VOLATILE_P (mem)); For relaxed and release memory models, we don't need this. But we
also don't bother trying to prevent it either. */
gcc_assert (model == MEMMODEL_RELAXED
|| model == MEMMODEL_RELEASE
|| MEM_VOLATILE_P (mem));
old_reg = gen_reg_rtx (DImode); old_reg = gen_reg_rtx (DImode);
cmp_reg = gen_reg_rtx (DImode); cmp_reg = gen_reg_rtx (DImode);
...@@ -2342,6 +2365,25 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, ...@@ -2342,6 +2365,25 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
if (new_dst) if (new_dst)
emit_move_insn (new_dst, new_reg); emit_move_insn (new_dst, new_reg);
switch (model)
{
case MEMMODEL_RELAXED:
case MEMMODEL_ACQUIRE:
case MEMMODEL_CONSUME:
switch (mode)
{
case QImode: icode = CODE_FOR_cmpxchg_acq_qi; break;
case HImode: icode = CODE_FOR_cmpxchg_acq_hi; break;
case SImode: icode = CODE_FOR_cmpxchg_acq_si; break;
case DImode: icode = CODE_FOR_cmpxchg_acq_di; break;
default:
gcc_unreachable ();
}
break;
case MEMMODEL_RELEASE:
case MEMMODEL_ACQ_REL:
case MEMMODEL_SEQ_CST:
switch (mode) switch (mode)
{ {
case QImode: icode = CODE_FOR_cmpxchg_rel_qi; break; case QImode: icode = CODE_FOR_cmpxchg_rel_qi; break;
...@@ -2351,6 +2393,11 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val, ...@@ -2351,6 +2393,11 @@ ia64_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
default: default:
gcc_unreachable (); gcc_unreachable ();
} }
break;
default:
gcc_unreachable ();
}
emit_insn (GEN_FCN (icode) (cmp_reg, mem, ar_ccv, new_reg)); emit_insn (GEN_FCN (icode) (cmp_reg, mem, ar_ccv, new_reg));
...@@ -6342,6 +6389,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred) ...@@ -6342,6 +6389,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
case UNSPEC_PIC_CALL: case UNSPEC_PIC_CALL:
case UNSPEC_MF: case UNSPEC_MF:
case UNSPEC_FETCHADD_ACQ: case UNSPEC_FETCHADD_ACQ:
case UNSPEC_FETCHADD_REL:
case UNSPEC_BSP_VALUE: case UNSPEC_BSP_VALUE:
case UNSPEC_FLUSHRS: case UNSPEC_FLUSHRS:
case UNSPEC_BUNDLE_SELECTOR: case UNSPEC_BUNDLE_SELECTOR:
...@@ -6385,6 +6433,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred) ...@@ -6385,6 +6433,7 @@ rtx_needs_barrier (rtx x, struct reg_flags flags, int pred)
break; break;
case UNSPEC_CMPXCHG_ACQ: case UNSPEC_CMPXCHG_ACQ:
case UNSPEC_CMPXCHG_REL:
need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred); need_barrier = rtx_needs_barrier (XVECEXP (x, 0, 1), flags, pred);
need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 2), flags, pred); need_barrier |= rtx_needs_barrier (XVECEXP (x, 0, 2), flags, pred);
break; break;
......
...@@ -68,7 +68,9 @@ ...@@ -68,7 +68,9 @@
UNSPEC_PIC_CALL UNSPEC_PIC_CALL
UNSPEC_MF UNSPEC_MF
UNSPEC_CMPXCHG_ACQ UNSPEC_CMPXCHG_ACQ
UNSPEC_CMPXCHG_REL
UNSPEC_FETCHADD_ACQ UNSPEC_FETCHADD_ACQ
UNSPEC_FETCHADD_REL
UNSPEC_BSP_VALUE UNSPEC_BSP_VALUE
UNSPEC_FLUSHRS UNSPEC_FLUSHRS
UNSPEC_BUNDLE_SELECTOR UNSPEC_BUNDLE_SELECTOR
......
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