diff options
author | Walter Lee <walt@tilera.com> | 2013-03-21 02:08:26 +0000 |
---|---|---|
committer | Walter Lee <walt@gcc.gnu.org> | 2013-03-21 02:08:26 +0000 |
commit | 327a1118271129829e9ac0abd894eb29254b93eb (patch) | |
tree | a117d6b2813f6b1519daa1b6d00e0cb782998c4f /gcc | |
parent | f7e1f1f149ba01858f0108c8c91bb14f0ef02cee (diff) | |
download | gcc-327a1118271129829e9ac0abd894eb29254b93eb.zip gcc-327a1118271129829e9ac0abd894eb29254b93eb.tar.gz gcc-327a1118271129829e9ac0abd894eb29254b93eb.tar.bz2 |
Add an atomic test and set pattern on tilegx.
* config/tilegx/sync.md (atomic_test_and_set): New pattern.
From-SVN: r196848
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/config/tilegx/sync.md | 46 |
2 files changed, 50 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2cd7169..5ecdc8f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2013-03-20 Walter Lee <walt@tilera.com> + + * config/tilegx/sync.md (atomic_test_and_set): New pattern. + 2013-03-20 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.md (*movoi_internal_avx): Emit insn template diff --git a/gcc/config/tilegx/sync.md b/gcc/config/tilegx/sync.md index a853996..a4bea6b 100644 --- a/gcc/config/tilegx/sync.md +++ b/gcc/config/tilegx/sync.md @@ -162,3 +162,49 @@ tilegx_post_atomic_barrier (model); DONE; }) + + +(define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") ;; bool output + (match_operand:QI 1 "nonautoincmem_operand" "+U") ;; memory + (match_operand:SI 2 "const_int_operand" "")] ;; model + "" +{ + rtx addr, aligned_addr, aligned_mem, offset, word, shmt; + rtx tmp0, tmp1; + rtx result = operands[0]; + rtx mem = operands[1]; + enum memmodel model = (enum memmodel) INTVAL (operands[2]); + + addr = force_reg (Pmode, XEXP (mem, 0)); + + aligned_addr = gen_reg_rtx (Pmode); + emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-8))); + + aligned_mem = change_address (mem, DImode, aligned_addr); + set_mem_alias_set (aligned_mem, 0); + + offset = gen_reg_rtx (DImode); + emit_move_insn (offset, gen_rtx_AND (DImode, gen_lowpart (DImode, addr), + GEN_INT (7))); + + tmp0 = gen_reg_rtx (DImode); + emit_move_insn (tmp0, GEN_INT (1)); + + shmt = gen_reg_rtx (DImode); + emit_move_insn (shmt, gen_rtx_ASHIFT (DImode, offset, GEN_INT (3))); + + word = gen_reg_rtx (DImode); + emit_move_insn (word, gen_rtx_ASHIFT (DImode, tmp0, + gen_lowpart (SImode, shmt))); + + tmp1 = gen_reg_rtx (DImode); + tilegx_pre_atomic_barrier (model); + emit_insn (gen_atomic_fetch_or_baredi (tmp1, aligned_mem, word)); + tilegx_post_atomic_barrier (model); + + emit_move_insn (gen_lowpart (DImode, result), + gen_rtx_LSHIFTRT (DImode, tmp1, + gen_lowpart (SImode, shmt))); + DONE; +}) |