OSDN Git Service

sparc: Fix atomic_test_and_set definition.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 2012 22:04:54 +0000 (22:04 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 2012 22:04:54 +0000 (22:04 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183584 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sync.md

index bbe300f..32a21d2 100644 (file)
@@ -1,5 +1,12 @@
 2012-01-27  Richard Henderson  <rth@redhat.com>
 
+       * 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.
+
+2012-01-27  Richard Henderson  <rth@redhat.com>
+
        * target.def (TARGET_ATOMIC_TEST_AND_SET_TRUEVAL): New.
        * c-cppbuiltin.c (cpp_atomic_builtins): Define
        __GCC_ATOMIC_TEST_AND_SET_TRUEVAL.
index 19ab54a..1b3b4c8 100644 (file)
@@ -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
index be8c4c4..d07d572 100644 (file)
   "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))
   ""
   "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")])