diff options
author | Richard Henderson <rth@redhat.com> | 2012-01-26 14:04:54 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2012-01-26 14:04:54 -0800 |
commit | 5a843a13dca3c000691cfd9f1570500ad2d53efe (patch) | |
tree | 8569dd89808813466188f10220f75214bc31da2e /gcc/config/sparc | |
parent | f10f4968960c57a349467e833a29e3a52b4fff41 (diff) | |
download | gcc-5a843a13dca3c000691cfd9f1570500ad2d53efe.tar.gz |
sparc: Fix atomic_test_and_set definition.
* config/sparc/sparc.c (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New.
* config/sparc/sync.md (atomic_test_and_set): Only handle QImode.
(ldstub): Rename from ldstubqi.
(ldstub<I24MODE>): Remove.
From-SVN: r183584
Diffstat (limited to 'gcc/config/sparc')
-rw-r--r-- | gcc/config/sparc/sparc.c | 4 | ||||
-rw-r--r-- | gcc/config/sparc/sync.md | 31 |
2 files changed, 17 insertions, 18 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 19ab54a1304..1b3b4c8764c 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -779,6 +779,10 @@ char sparc_hard_reg_printed[8]; #undef TARGET_PRINT_OPERAND_ADDRESS #define TARGET_PRINT_OPERAND_ADDRESS sparc_print_operand_address +/* The value stored by LDSTUB. */ +#undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL +#define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 0xff + struct gcc_target targetm = TARGET_INITIALIZER; static void diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md index be8c4c4783a..d07d572c614 100644 --- a/gcc/config/sparc/sync.md +++ b/gcc/config/sparc/sync.md @@ -242,25 +242,30 @@ "swap\t%1, %0" [(set_attr "type" "multi")]) -(define_expand "atomic_test_and_set<mode>" - [(match_operand:I124MODE 0 "register_operand" "") - (match_operand:I124MODE 1 "memory_operand" "") +(define_expand "atomic_test_and_set" + [(match_operand:QI 0 "register_operand" "") + (match_operand:QI 1 "memory_operand" "") (match_operand:SI 2 "const_int_operand" "")] "" { enum memmodel model = (enum memmodel) INTVAL (operands[2]); + rtx ret; sparc_emit_membar_for_model (model, 3, 1); + emit_insn (gen_ldstub (operands[0], operands[1])); + sparc_emit_membar_for_model (model, 3, 2); - if (<MODE>mode != QImode) - operands[1] = adjust_address (operands[1], QImode, 0); - emit_insn (gen_ldstub<mode> (operands[0], operands[1])); + /* Convert the 0/0xff result we would otherwise have to a boolean. + I.e. ignore all but bit 0. */ + ret = expand_simple_binop (QImode, AND, operands[0], const1_rtx, + operands[0], true, OPTAB_LIB_WIDEN); + if (ret != operands[0]) + emit_move_insn (operands[0], ret); - sparc_emit_membar_for_model (model, 3, 2); DONE; }) -(define_insn "ldstubqi" +(define_insn "ldstub" [(set (match_operand:QI 0 "register_operand" "=r") (unspec_volatile:QI [(match_operand:QI 1 "memory_operand" "+m")] UNSPECV_LDSTUB)) @@ -268,13 +273,3 @@ "" "ldstub\t%1, %0" [(set_attr "type" "multi")]) - -(define_insn "ldstub<mode>" - [(set (match_operand:I24MODE 0 "register_operand" "=r") - (zero_extend:I24MODE - (unspec_volatile:QI [(match_operand:QI 1 "memory_operand" "+m")] - UNSPECV_LDSTUB))) - (set (match_dup 1) (const_int -1))] - "" - "ldstub\t%1, %0" - [(set_attr "type" "multi")]) |