This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] MIPS: Fix __sync_nand for changed semantics.


The decision to change the semantics of the built-in atomic NAND
operations necessitates some changes for MIPS.

This patch fixes the five newly failing testcases:

-FAIL: gcc.dg/ia64-sync-1.c execution test
+PASS: gcc.dg/ia64-sync-1.c execution test

-FAIL: gcc.dg/ia64-sync-2.c execution test
+PASS: gcc.dg/ia64-sync-2.c execution test

-FAIL: gcc.dg/pr37908.c execution test
+PASS: gcc.dg/pr37908.c execution test

-FAIL: gcc.dg/sync-2.c execution test
+PASS: gcc.dg/sync-2.c execution test

-FAIL: gcc.dg/sync-3.c execution test
+PASS: gcc.dg/sync-3.c execution test

We do however suffer a new failure in gcc.target/mips/atomic-memory-1.c,
which is due to the change in semantics.  Someone will have to fix this
with a separate patch to the testcase.

Tested on mips64-octeon-linux w/ n32 ABI.

OK to commit?

2008-12-05 David Daney <ddaney@caviumnetworks.com>

	* config/mips/sync.md (sync_old_<optab>_12): Remove third
	paramater to MIPS_SYNC_OLD_OP_12 macro.
	(sync_nand_12): Reduce length attribute to 40.
	(sync_old_nand_12): Remove third paramater to MIPS_SYNC_OLD_OP_12
	macro, and reduce length attribute to 40.
	(sync_new_nand<mode>): Increase length attribute to 36.
	* config/mips/mips.h (MIPS_SYNC_OP_12, MIPS_SYNC_OP_12_NOT_NOP,
	MIPS_SYNC_OP_12_NOT_NOT,MIPS_SYNC_OLD_OP_12_NOT_NOP,
	MIPS_SYNC_OLD_OP_12_NOT_NOT, MIPS_SYNC_NEW_OP_12,
	MIPS_SYNC_NEW_OP_12_NOT_NOP, MIPS_SYNC_NEW_OP_12_NOT_NOT,
	MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND, MIPS_SYNC_NEW_NAND): Rewritten
	to implement new __sync_nand semantics.
	(MIPS_SYNC_OLD_OP_12): Implement new __sync_nand semantics, and
	remove third parameter.
	(MIPS_SYNC_OLD_OP_12_NOT_NOP_REG,
	MIPS_SYNC_OLD_OP_12_NOT_NOT_REG): Removed.
	

Index: config/mips/sync.md
===================================================================
--- config/mips/sync.md	(revision 142423)
+++ config/mips/sync.md	(working copy)
@@ -164,8 +164,7 @@ (define_insn "sync_old_<optab>_12"
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-	    (MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP,
-	    			  MIPS_SYNC_OLD_OP_12_NOT_NOP_REG)));
+	    (MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP)));
 }
   [(set_attr "length" "40")])
 
@@ -241,7 +240,7 @@ (define_insn "sync_nand_12"
     return (mips_output_sync_loop
 	    (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT)));
 }
-  [(set_attr "length" "44")])
+  [(set_attr "length" "40")])
 
 (define_expand "sync_old_nand<mode>"
   [(parallel [
@@ -274,10 +273,9 @@ (define_insn "sync_old_nand_12"
   "GENERATE_LL_SC"
 {
     return (mips_output_sync_loop
-	    (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT,
-				  MIPS_SYNC_OLD_OP_12_NOT_NOT_REG)));
+	    (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT)));
 }
-  [(set_attr "length" "44")])
+  [(set_attr "length" "40")])
 
 (define_expand "sync_new_nand<mode>"
   [(parallel [
@@ -485,7 +483,7 @@ (define_insn "sync_new_nand<mode>"
   else
     return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("<d>", "and"));
 }
-  [(set_attr "length" "32")])
+  [(set_attr "length" "36")])
 
 (define_insn "sync_lock_test_and_set<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=&d,&d")
Index: config/mips/mips.h
===================================================================
--- config/mips/mips.h	(revision 142423)
+++ config/mips/mips.h	(working copy)
@@ -3183,24 +3183,23 @@ while (0)
 
      - Uses scratch register %4.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_OP_12(INSN, NOT_OP)		\
+    AND_OP are the instructions done after the INSN to mask the INSN's
+    result with the mask.  In the case of the sync_nand operation, it
+    also does the bit-wise not that is required after the AND INSN.  */
+#define MIPS_SYNC_OP_12(INSN, AND_OP)		\
   "%(%<%[%|sync\n"				\
   "1:\tll\t%4,%0\n"				\
   "\tand\t%@,%4,%2\n"				\
-  NOT_OP					\
   "\t" INSN "\t%4,%4,%z3\n"			\
-  "\tand\t%4,%4,%1\n"				\
+  AND_OP					\
   "\tor\t%@,%@,%4\n"				\
   "\tsc\t%@,%0\n"				\
   "\tbeq%?\t%@,%.,1b\n"				\
   "\tnop\n"					\
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OP_12_NOT_NOT "\tnor\t%4,%4,%.\n"
+#define MIPS_SYNC_OP_12_NOT_NOP "\tand\t%4,%4,%1\n"
+#define MIPS_SYNC_OP_12_NOT_NOT "\txor\t%4,%4,%1\n"
 
 /* Return an asm string that atomically:
 
@@ -3213,29 +3212,23 @@ while (0)
 
      - Uses scratch register %5.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.
-
-    REG is used in conjunction with NOT_OP and is used to select the
-    register operated on by the INSN.  */
-#define MIPS_SYNC_OLD_OP_12(INSN, NOT_OP, REG)	\
+    AND_OP are the instructions done after the INSN to mask the INSN's
+    result with the mask.  In the case of the sync_nand operation, it
+    also does the bit-wise not that is required after the AND INSN.  */
+#define MIPS_SYNC_OLD_OP_12(INSN, AND_OP)	\
   "%(%<%[%|sync\n"				\
   "1:\tll\t%0,%1\n"				\
   "\tand\t%@,%0,%3\n"				\
-  NOT_OP					\
-  "\t" INSN "\t%5," REG ",%z4\n"		\
-  "\tand\t%5,%5,%2\n"				\
+  "\t" INSN "\t%5,%0,%z4\n"			\
+  AND_OP					\
   "\tor\t%@,%@,%5\n"				\
   "\tsc\t%@,%1\n"				\
   "\tbeq%?\t%@,%.,1b\n"				\
   "\tnop\n"					\
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP ""
-#define MIPS_SYNC_OLD_OP_12_NOT_NOP_REG "%0"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT "\tnor\t%5,%0,%.\n"
-#define MIPS_SYNC_OLD_OP_12_NOT_NOT_REG "%5"
+#define MIPS_SYNC_OLD_OP_12_NOT_NOP "\tand\t%5,%5,%2\n"
+#define MIPS_SYNC_OLD_OP_12_NOT_NOT "\txor\t%5,%5,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3246,24 +3239,23 @@ while (0)
 
      - Sets %0 to the new value of %1.
 
-    NOT_OP are the optional instructions to do a bit-wise not
-    operation in conjunction with an AND INSN to generate a sync_nand
-    operation.  */
-#define MIPS_SYNC_NEW_OP_12(INSN, NOT_OP)	\
+    AND_OP are the instructions done after the INSN to mask the INSN's
+    result with the mask.  In the case of the sync_nand operation, it
+    also does the bit-wise not that is required after the AND INSN.  */
+#define MIPS_SYNC_NEW_OP_12(INSN, AND_OP)	\
   "%(%<%[%|sync\n"				\
   "1:\tll\t%0,%1\n"				\
   "\tand\t%@,%0,%3\n"				\
-  NOT_OP					\
   "\t" INSN "\t%0,%0,%z4\n"			\
-  "\tand\t%0,%0,%2\n"				\
+  AND_OP					\
   "\tor\t%@,%@,%0\n"				\
   "\tsc\t%@,%1\n"				\
   "\tbeq%?\t%@,%.,1b\n"				\
   "\tnop\n"					\
   "\tsync%-%]%>%)"
 
-#define MIPS_SYNC_NEW_OP_12_NOT_NOP ""
-#define MIPS_SYNC_NEW_OP_12_NOT_NOT "\tnor\t%0,%0,%.\n"
+#define MIPS_SYNC_NEW_OP_12_NOT_NOP "\tand\t%0,%0,%2\n"
+#define MIPS_SYNC_NEW_OP_12_NOT_NOT "\txor\t%0,%0,%2\n"
 
 /* Return an asm string that atomically:
 
@@ -3301,7 +3293,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %0 to ~%0 AND %1.
+     - Sets memory reference %0 to ~(%0 AND %1).
 
    SUFFIX is the suffix that should be added to "ll" and "sc"
    instructions.  INSN is the and instruction needed to and a register
@@ -3309,8 +3301,8 @@ while (0)
 #define MIPS_SYNC_NAND(SUFFIX, INSN)		\
   "%(%<%[%|sync\n"				\
   "1:\tll" SUFFIX "\t%@,%0\n"			\
-  "\tnor\t%@,%@,%.\n"				\
   "\t" INSN "\t%@,%@,%1\n"			\
+  "\tnor\t%@,%@,%.\n"				\
   "\tsc" SUFFIX "\t%@,%0\n"			\
   "\tbeq%?\t%@,%.,1b\n"				\
   "\tnop\n"					\
@@ -3318,7 +3310,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the old value of memory reference %1.
 
@@ -3328,8 +3320,8 @@ while (0)
 #define MIPS_SYNC_OLD_NAND(SUFFIX, INSN)	\
   "%(%<%[%|sync\n"				\
   "1:\tll" SUFFIX "\t%0,%1\n"			\
-  "\tnor\t%@,%0,%.\n"				\
-  "\t" INSN "\t%@,%@,%2\n"			\
+  "\t" INSN "\t%@,%0,%2\n"			\
+  "\tnor\t%@,%@,%.\n"				\
   "\tsc" SUFFIX "\t%@,%1\n"			\
   "\tbeq%?\t%@,%.,1b\n"				\
   "\tnop\n"					\
@@ -3337,7 +3329,7 @@ while (0)
 
 /* Return an asm string that atomically:
 
-     - Sets memory reference %1 to ~%1 AND %2.
+     - Sets memory reference %1 to ~(%1 AND %2).
 
      - Sets register %0 to the new value of memory reference %1.
 
@@ -3347,11 +3339,12 @@ while (0)
 #define MIPS_SYNC_NEW_NAND(SUFFIX, INSN)	\
   "%(%<%[%|sync\n"				\
   "1:\tll" SUFFIX "\t%0,%1\n"			\
-  "\tnor\t%0,%0,%.\n"				\
   "\t" INSN "\t%@,%0,%2\n"			\
+  "\tnor\t%@,%@,%.\n"				\
+  "\tmove\t%0,%@\n"				\
   "\tsc" SUFFIX "\t%@,%1\n"			\
   "\tbeq%?\t%@,%.,1b%~\n"			\
-  "\t" INSN "\t%0,%0,%2\n"			\
+  "\tnop\n"					\
   "\tsync%-%]%>%)"
 
 /* Return an asm string that atomically:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]