This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] MIPS: Fix __sync_nand for changed semantics.
- From: David Daney <ddaney at caviumnetworks dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 05 Dec 2008 12:21:09 -0800
- Subject: [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: