summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-15 14:26:07 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-15 14:26:07 +0000
commit749bd779032567a20ca707479d73a68311572d54 (patch)
tree3d42c705e5726ec340df30a25b4740a024daf292
parent14a80f8f04a2868d2eef795ca6b1e51bb43e1704 (diff)
downloadgcc-749bd779032567a20ca707479d73a68311572d54.tar.gz
gcc/
2008-11-15 Joshua Kinard <kumba@gentoo.org> * doc/invoke.texi (-mfix-r10000): Document. * config/mips/mips.opt (mfix-r10000): New option. * config/mips/mips-protos.h (mips_output_sync_loop): Declare. * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Use %?. (MIPS_COMPARE_AND_SWAP_12): Likewise. (MIPS_SYNC_OP): Likewise. (MIPS_SYNC_OP_12): Likewise. (MIPS_SYNC_OLD_OP_12): Likewise. (MIPS_SYNC_NEW_OP_12): Likewise. (MIPS_SYNC_OLD_OP): Likewise. (MIPS_SYNC_NAND): Likewise. (MIPS_SYNC_OLD_NAND): Likewise. (MIPS_SYNC_EXCHANGE): Likewise. (MIPS_SYNC_EXCHANGE_12): Likewise. (MIPS_SYNC_NEW_OP): Likewise, using %~ to fill branch-likely delay slots. (MIPS_SYNC_NEW_NAND): Likewise. * config/mips/mips.c (mips_print_operand_punctuation): Handle '~'. (mips_init_print_operand_punct): Treat '~' as a punctuation character. (mips_output_sync_loop): New function. (mips_override_options): Make -march=r10000 imply -mfix-r10000. Make -mfix-r10000 require branch-likely instructions. * config/mips/sync.md (sync_compare_and_swap<mode>): Use mips_output_sync_loop. (compare_and_swap_12): Likewise. (sync_add<mode>): Likewise. (sync_<optab>_12): Likewise. (sync_old_<optab>_12): Likewise. (sync_new_<optab>_12): Likewise. (sync_nand_12): Likewise. (sync_old_nand_12): Likewise. (sync_new_nand_12): Likewise. (sync_sub<mode>): Likewise. (sync_old_add<mode>): Likewise. (sync_old_sub<mode>): Likewise. (sync_new_add<mode>): Likewise. (sync_new_sub<mode>): Likewise. (sync_<optab><mode>): Likewise. (sync_old_<optab><mode>): Likewise. (sync_new_<optab><mode>): Likewise. (sync_nand<mode>): Likewise. (sync_old_nand<mode>): Likewise. (sync_new_nand<mode>): Likewise. (sync_lock_test_and_set<mode>): Likewise. (test_and_set_12): Likewise. gcc/testsuite/ 2008-11-15 Joshua Kinard <kumba@gentoo.org> Richard Sandiford <rdsandiford@goolemail.com> * gcc.target/mips/fix-r10000-1.c: New test. * gcc.target/mips/fix-r10000-2.c: Likewise. * gcc.target/mips/fix-r10000-3.c: Likewise. * gcc.target/mips/fix-r10000-4.c: Likewise. * gcc.target/mips/fix-r10000-5.c: Likewise. * gcc.target/mips/fix-r10000-6.c: Likewise. * gcc.target/mips/fix-r10000-7.c: Likewise. * gcc.target/mips/fix-r10000-8.c: Likewise. * gcc.target/mips/fix-r10000-9.c: Likewise. * gcc.target/mips/fix-r10000-10.c: Likewise. * gcc.target/mips/fix-r10000-11.c: Likewise. * gcc.target/mips/fix-r10000-12.c: Likewise. * gcc.target/mips/fix-r10000-13.c: Likewise. * gcc.target/mips/fix-r10000-14.c: Likewise. * gcc.target/mips/fix-r10000-15.c: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@141886 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog48
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c37
-rw-r--r--gcc/config/mips/mips.h26
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/config/mips/sync.md86
-rw-r--r--gcc/doc/invoke.texi20
-rw-r--r--gcc/testsuite/ChangeLog19
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-1.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-10.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-11.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-12.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-13.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-14.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-15.c33
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-2.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-3.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-4.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-5.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-6.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-7.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-8.c21
-rw-r--r--gcc/testsuite/gcc.target/mips/fix-r10000-9.c21
23 files changed, 515 insertions, 53 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3c9d65c06c3..a4e4609f57d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,51 @@
+2008-11-15 Joshua Kinard <kumba@gentoo.org>
+
+ * doc/invoke.texi (-mfix-r10000): Document.
+ * config/mips/mips.opt (mfix-r10000): New option.
+ * config/mips/mips-protos.h (mips_output_sync_loop): Declare.
+ * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Use %?.
+ (MIPS_COMPARE_AND_SWAP_12): Likewise.
+ (MIPS_SYNC_OP): Likewise.
+ (MIPS_SYNC_OP_12): Likewise.
+ (MIPS_SYNC_OLD_OP_12): Likewise.
+ (MIPS_SYNC_NEW_OP_12): Likewise.
+ (MIPS_SYNC_OLD_OP): Likewise.
+ (MIPS_SYNC_NAND): Likewise.
+ (MIPS_SYNC_OLD_NAND): Likewise.
+ (MIPS_SYNC_EXCHANGE): Likewise.
+ (MIPS_SYNC_EXCHANGE_12): Likewise.
+ (MIPS_SYNC_NEW_OP): Likewise, using %~ to fill branch-likely
+ delay slots.
+ (MIPS_SYNC_NEW_NAND): Likewise.
+ * config/mips/mips.c (mips_print_operand_punctuation): Handle '~'.
+ (mips_init_print_operand_punct): Treat '~' as a punctuation character.
+ (mips_output_sync_loop): New function.
+ (mips_override_options): Make -march=r10000 imply -mfix-r10000.
+ Make -mfix-r10000 require branch-likely instructions.
+ * config/mips/sync.md (sync_compare_and_swap<mode>): Use
+ mips_output_sync_loop.
+ (compare_and_swap_12): Likewise.
+ (sync_add<mode>): Likewise.
+ (sync_<optab>_12): Likewise.
+ (sync_old_<optab>_12): Likewise.
+ (sync_new_<optab>_12): Likewise.
+ (sync_nand_12): Likewise.
+ (sync_old_nand_12): Likewise.
+ (sync_new_nand_12): Likewise.
+ (sync_sub<mode>): Likewise.
+ (sync_old_add<mode>): Likewise.
+ (sync_old_sub<mode>): Likewise.
+ (sync_new_add<mode>): Likewise.
+ (sync_new_sub<mode>): Likewise.
+ (sync_<optab><mode>): Likewise.
+ (sync_old_<optab><mode>): Likewise.
+ (sync_new_<optab><mode>): Likewise.
+ (sync_nand<mode>): Likewise.
+ (sync_old_nand<mode>): Likewise.
+ (sync_new_nand<mode>): Likewise.
+ (sync_lock_test_and_set<mode>): Likewise.
+ (test_and_set_12): Likewise.
+
2008-11-15 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c (cc1_options): Fix comment.
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 9403945a4f3..3fa67c982ea 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -300,6 +300,7 @@ extern const char *mips_output_load_label (void);
extern const char *mips_output_conditional_branch (rtx, rtx *, const char *,
const char *);
extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool);
+extern const char *mips_output_sync_loop (const char *);
extern const char *mips_output_division (const char *, rtx *);
extern unsigned int mips_hard_regno_nregs (int, enum machine_mode);
extern bool mips_linked_madd_p (rtx, rtx);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index fa78c8bf270..5198fd32ddc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -6909,6 +6909,7 @@ mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
'#' Print a nop if in a ".set noreorder" block.
'/' Like '#', but do nothing within a delayed-branch sequence.
'?' Print "l" if mips_branch_likely is true
+ '~' Print a nop if mips_branch_likely is true
'.' Print the name of the register with a hard-wired zero (zero or $0).
'@' Print the name of the assembler temporary register (at or $1).
'^' Print the name of the pic call-through register (t9 or $25).
@@ -6983,6 +6984,11 @@ mips_print_operand_punctuation (FILE *file, int ch)
putc ('l', file);
break;
+ case '~':
+ if (mips_branch_likely)
+ fputs ("\n\tnop", file);
+ break;
+
case '.':
fputs (reg_names[GP_REG_FIRST + 0], file);
break;
@@ -7026,7 +7032,7 @@ mips_init_print_operand_punct (void)
{
const char *p;
- for (p = "()[]<>*#/?.@^+$|-"; *p; p++)
+ for (p = "()[]<>*#/?~.@^+$|-"; *p; p++)
mips_print_operand_punct[(unsigned char) *p] = true;
}
@@ -10250,6 +10256,17 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p)
return mips_output_conditional_branch (insn, operands, branch[1], branch[0]);
}
+/* Return the assembly code for __sync_*() loop LOOP. The loop should support
+ both normal and likely branches, using %? and %~ where appropriate. */
+
+const char *
+mips_output_sync_loop (const char *loop)
+{
+ /* Use branch-likely instructions to work around the LL/SC R10000 errata. */
+ mips_branch_likely = TARGET_FIX_R10000;
+ return loop;
+}
+
/* Return the assembly code for DIV or DDIV instruction DIVISION, which has
the operands given by OPERANDS. Add in a divide-by-zero check if needed.
@@ -13971,6 +13988,24 @@ mips_override_options (void)
&& mips_matching_cpu_name_p (mips_arch_info->name, "r4400"))
target_flags |= MASK_FIX_R4400;
+ /* Default to working around R10000 errata only if the processor
+ was selected explicitly. */
+ if ((target_flags_explicit & MASK_FIX_R10000) == 0
+ && mips_matching_cpu_name_p (mips_arch_info->name, "r10000"))
+ target_flags |= MASK_FIX_R10000;
+
+ /* Make sure that branch-likely instructions available when using
+ -mfix-r10000. The instructions are not available if either:
+
+ 1. -mno-branch-likely was passed.
+ 2. The selected ISA does not support branch-likely and
+ the command line does not include -mbranch-likely. */
+ if (TARGET_FIX_R10000
+ && ((target_flags_explicit & MASK_BRANCHLIKELY) == 0
+ ? !ISA_HAS_BRANCHLIKELY
+ : !TARGET_BRANCHLIKELY))
+ sorry ("%qs requires branch-likely instructions", "-mfix-r10000");
+
/* Save base state of options. */
mips_base_target_flags = target_flags;
mips_base_delayed_branch = flag_delayed_branch;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 354c4c5f1c3..8ae2b206fae 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -3090,7 +3090,7 @@ while (0)
"\tbne\t%0,%z2,2f\n" \
"\t" OP "\t%@,%3\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)\n" \
"2:\n"
@@ -3115,7 +3115,7 @@ while (0)
"\tand\t%@,%0,%3\n" \
OPS \
"\tsc\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)\n" \
"2:\n"
@@ -3135,7 +3135,7 @@ while (0)
"1:\tll" SUFFIX "\t%@,%0\n" \
"\t" INSN "\t%@,%@,%1\n" \
"\tsc" SUFFIX "\t%@,%0\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3160,7 +3160,7 @@ while (0)
"\tand\t%4,%4,%1\n" \
"\tor\t%@,%@,%4\n" \
"\tsc\t%@,%0\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3193,7 +3193,7 @@ while (0)
"\tand\t%5,%5,%2\n" \
"\tor\t%@,%@,%5\n" \
"\tsc\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3223,7 +3223,7 @@ while (0)
"\tand\t%0,%0,%2\n" \
"\tor\t%@,%@,%0\n" \
"\tsc\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3243,7 +3243,7 @@ while (0)
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3260,7 +3260,7 @@ while (0)
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b%~\n" \
"\t" INSN "\t%0,%0,%2\n" \
"\tsync%-%]%>%)"
@@ -3277,7 +3277,7 @@ while (0)
"\tnor\t%@,%@,%.\n" \
"\t" INSN "\t%@,%@,%1\n" \
"\tsc" SUFFIX "\t%@,%0\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3296,7 +3296,7 @@ while (0)
"\tnor\t%@,%0,%.\n" \
"\t" INSN "\t%@,%@,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3315,7 +3315,7 @@ while (0)
"\tnor\t%0,%0,%.\n" \
"\t" INSN "\t%@,%0,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b%~\n" \
"\t" INSN "\t%0,%0,%2\n" \
"\tsync%-%]%>%)"
@@ -3333,7 +3333,7 @@ while (0)
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" OP "\t%@,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
@@ -3357,7 +3357,7 @@ while (0)
"\tand\t%@,%0,%3\n" \
OPS \
"\tsc\t%@,%1\n" \
- "\tbeq\t%@,%.,1b\n" \
+ "\tbeq%?\t%@,%.,1b\n" \
"\tnop\n" \
"\tsync%-%]%>%)"
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index f192f0b52b8..c7e78ff5d13 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -112,6 +112,10 @@ mfix-r4400
Target Report Mask(FIX_R4400)
Work around certain R4400 errata
+mfix-r10000
+Target Report Mask(FIX_R10000)
+Work around certain R10000 errata
+
mfix-sb1
Target Report Var(TARGET_FIX_SB1)
Work around errata for early SB-1 revision 2 cores
diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md
index 0052f46dc9f..286ca369214 100644
--- a/gcc/config/mips/sync.md
+++ b/gcc/config/mips/sync.md
@@ -43,9 +43,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_COMPARE_AND_SWAP ("<d>", "li");
+ return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("<d>", "li"));
else
- return MIPS_COMPARE_AND_SWAP ("<d>", "move");
+ return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("<d>", "move"));
}
[(set_attr "length" "32")])
@@ -76,9 +76,11 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP);
+ return (mips_output_sync_loop
+ (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP)));
else
- return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP);
+ return (mips_output_sync_loop
+ (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP)));
}
[(set_attr "length" "40,36")])
@@ -91,9 +93,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_OP ("<d>", "<d>addiu");
+ return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>addiu"));
else
- return MIPS_SYNC_OP ("<d>", "<d>addu");
+ return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>addu"));
}
[(set_attr "length" "28")])
@@ -124,7 +126,8 @@
(clobber (match_scratch:SI 4 "=&d"))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP)));
}
[(set_attr "length" "40")])
@@ -160,8 +163,9 @@
(clobber (match_scratch:SI 5 "=&d"))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP,
- MIPS_SYNC_OLD_OP_12_NOT_NOP_REG);
+ 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)));
}
[(set_attr "length" "40")])
@@ -202,7 +206,8 @@
(match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP)));
}
[(set_attr "length" "40")])
@@ -233,7 +238,8 @@
(clobber (match_scratch:SI 4 "=&d"))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT)));
}
[(set_attr "length" "44")])
@@ -267,8 +273,9 @@
(clobber (match_scratch:SI 5 "=&d"))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT,
- MIPS_SYNC_OLD_OP_12_NOT_NOT_REG);
+ 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)));
}
[(set_attr "length" "44")])
@@ -307,7 +314,8 @@
(match_dup 4)] UNSPEC_SYNC_NEW_OP_12))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT)));
}
[(set_attr "length" "40")])
@@ -319,7 +327,7 @@
UNSPEC_SYNC_OLD_OP))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OP ("<d>", "<d>subu");
+ return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>subu"));
}
[(set_attr "length" "28")])
@@ -334,9 +342,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>addiu"));
else
- return MIPS_SYNC_OLD_OP ("<d>", "<d>addu");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>addu"));
}
[(set_attr "length" "28")])
@@ -350,7 +358,7 @@
UNSPEC_SYNC_OLD_OP))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_OLD_OP ("<d>", "<d>subu");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>subu"));
}
[(set_attr "length" "28")])
@@ -365,9 +373,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>addiu"));
else
- return MIPS_SYNC_NEW_OP ("<d>", "<d>addu");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>addu"));
}
[(set_attr "length" "28")])
@@ -381,7 +389,7 @@
UNSPEC_SYNC_NEW_OP))]
"GENERATE_LL_SC"
{
- return MIPS_SYNC_NEW_OP ("<d>", "<d>subu");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>subu"));
}
[(set_attr "length" "28")])
@@ -394,9 +402,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_OP ("<d>", "<immediate_insn>");
+ return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<immediate_insn>"));
else
- return MIPS_SYNC_OP ("<d>", "<insn>");
+ return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<insn>"));
}
[(set_attr "length" "28")])
@@ -411,9 +419,10 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>");
+ return (mips_output_sync_loop
+ (MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>")));
else
- return MIPS_SYNC_OLD_OP ("<d>", "<insn>");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<insn>"));
}
[(set_attr "length" "28")])
@@ -428,9 +437,10 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>");
+ return (mips_output_sync_loop
+ (MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>")));
else
- return MIPS_SYNC_NEW_OP ("<d>", "<insn>");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<insn>"));
}
[(set_attr "length" "28")])
@@ -441,9 +451,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_NAND ("<d>", "andi");
+ return mips_output_sync_loop (MIPS_SYNC_NAND ("<d>", "andi"));
else
- return MIPS_SYNC_NAND ("<d>", "and");
+ return mips_output_sync_loop (MIPS_SYNC_NAND ("<d>", "and"));
}
[(set_attr "length" "32")])
@@ -456,9 +466,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_OLD_NAND ("<d>", "andi");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("<d>", "andi"));
else
- return MIPS_SYNC_OLD_NAND ("<d>", "and");
+ return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("<d>", "and"));
}
[(set_attr "length" "32")])
@@ -471,9 +481,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_NEW_NAND ("<d>", "andi");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("<d>", "andi"));
else
- return MIPS_SYNC_NEW_NAND ("<d>", "and");
+ return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("<d>", "and"));
}
[(set_attr "length" "32")])
@@ -486,9 +496,9 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_EXCHANGE ("<d>", "li");
+ return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("<d>", "li"));
else
- return MIPS_SYNC_EXCHANGE ("<d>", "move");
+ return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("<d>", "move"));
}
[(set_attr "length" "24")])
@@ -516,8 +526,10 @@
"GENERATE_LL_SC"
{
if (which_alternative == 0)
- return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP)));
else
- return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP);
+ return (mips_output_sync_loop
+ (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP)));
}
[(set_attr "length" "28,24")])
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ce621520fce..cc66b45c14b 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -668,8 +668,8 @@ Objective-C and Objective-C++ Dialects}.
-mmemcpy -mno-memcpy -mlong-calls -mno-long-calls @gol
-mmad -mno-mad -mfused-madd -mno-fused-madd -nocpp @gol
-mfix-r4000 -mno-fix-r4000 -mfix-r4400 -mno-fix-r4400 @gol
--mfix-vr4120 -mno-fix-vr4120 -mfix-vr4130 -mno-fix-vr4130 @gol
--mfix-sb1 -mno-fix-sb1 @gol
+-mfix-r10000 -mno-fix-r10000 -mfix-vr4120 -mno-fix-vr4120 @gol
+-mfix-vr4130 -mno-fix-vr4130 -mfix-sb1 -mno-fix-sb1 @gol
-mflush-func=@var{func} -mno-flush-func @gol
-mbranch-cost=@var{num} -mbranch-likely -mno-branch-likely @gol
-mfp-exceptions -mno-fp-exceptions @gol
@@ -12833,6 +12833,22 @@ A double-word or a variable shift may give an incorrect result if executed
immediately after starting an integer division.
@end itemize
+@item -mfix-r10000
+@itemx -mno-fix-r10000
+@opindex mfix-r10000
+@opindex mno-fix-r10000
+Work around certain R10000 errata:
+@itemize @minus
+@item
+@code{ll}/@code{sc} sequences may not behave atomically on revisions
+prior to 3.0. They may deadlock on revisions 2.6 and earlier.
+@end itemize
+
+This option can only be used if the target architecture supports
+branch-likely instructions. @option{-mfix-r10000} is the default when
+@option{-march=r10000} is used; @option{-mno-fix-r10000} is the default
+otherwise.
+
@item -mfix-vr4120
@itemx -mno-fix-vr4120
@opindex mfix-vr4120
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b64bf6356f7..1a4a0d29fe2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,22 @@
+2008-11-15 Joshua Kinard <kumba@gentoo.org>
+ Richard Sandiford <rdsandiford@goolemail.com>
+
+ * gcc.target/mips/fix-r10000-1.c: New test.
+ * gcc.target/mips/fix-r10000-2.c: Likewise.
+ * gcc.target/mips/fix-r10000-3.c: Likewise.
+ * gcc.target/mips/fix-r10000-4.c: Likewise.
+ * gcc.target/mips/fix-r10000-5.c: Likewise.
+ * gcc.target/mips/fix-r10000-6.c: Likewise.
+ * gcc.target/mips/fix-r10000-7.c: Likewise.
+ * gcc.target/mips/fix-r10000-8.c: Likewise.
+ * gcc.target/mips/fix-r10000-9.c: Likewise.
+ * gcc.target/mips/fix-r10000-10.c: Likewise.
+ * gcc.target/mips/fix-r10000-11.c: Likewise.
+ * gcc.target/mips/fix-r10000-12.c: Likewise.
+ * gcc.target/mips/fix-r10000-13.c: Likewise.
+ * gcc.target/mips/fix-r10000-14.c: Likewise.
+ * gcc.target/mips/fix-r10000-15.c: Likewise.
+
2008-11-15 Jakub Jelinek <jakub@redhat.com>
PR c++/37561
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-1.c b/gcc/testsuite/gcc.target/mips/fix-r10000-1.c
new file mode 100644
index 00000000000..e72974befc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_fetch_and_add (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_fetch_and_add (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_fetch_and_add (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-10.c b/gcc/testsuite/gcc.target/mips/fix-r10000-10.c
new file mode 100644
index 00000000000..a6dbfa3dfc7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-10.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_and_and_fetch (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_and_and_fetch (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_and_and_fetch (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-11.c b/gcc/testsuite/gcc.target/mips/fix-r10000-11.c
new file mode 100644
index 00000000000..4bf16e175a9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-11.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_xor_and_fetch (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_xor_and_fetch (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_xor_and_fetch (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-12.c b/gcc/testsuite/gcc.target/mips/fix-r10000-12.c
new file mode 100644
index 00000000000..0381c249e45
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-12.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_nand_and_fetch (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_nand_and_fetch (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_nand_and_fetch (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-13.c b/gcc/testsuite/gcc.target/mips/fix-r10000-13.c
new file mode 100644
index 00000000000..7e1efc85ab9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-13.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_bool_compare_and_swap (z, 0, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_bool_compare_and_swap (z, 0, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_bool_compare_and_swap (z, 0, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-14.c b/gcc/testsuite/gcc.target/mips/fix-r10000-14.c
new file mode 100644
index 00000000000..8d8fe095e34
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-14.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_val_compare_and_swap (z, 0, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_val_compare_and_swap (z, 0, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_val_compare_and_swap (z, 0, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-15.c b/gcc/testsuite/gcc.target/mips/fix-r10000-15.c
new file mode 100644
index 00000000000..fd7d0364bd7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-15.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ int result;
+
+ result = __sync_lock_test_and_set (z, 42);
+ __sync_lock_release (z);
+ return result;
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ short result;
+
+ result = __sync_lock_test_and_set (z, 42);
+ __sync_lock_release (z);
+ return result;
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ char result;
+
+ result = __sync_lock_test_and_set (z, 42);
+ __sync_lock_release (z);
+ return result;
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-2.c b/gcc/testsuite/gcc.target/mips/fix-r10000-2.c
new file mode 100644
index 00000000000..900a697c99e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z, int amt)
+{
+ return __sync_fetch_and_sub (z, amt);
+}
+
+NOMIPS16 short
+f2 (short *z, short amt)
+{
+ return __sync_fetch_and_sub (z, amt);
+}
+
+NOMIPS16 char
+f3 (char *z, char amt)
+{
+ return __sync_fetch_and_sub (z, amt);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-3.c b/gcc/testsuite/gcc.target/mips/fix-r10000-3.c
new file mode 100644
index 00000000000..de74e9724ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_fetch_and_or (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_fetch_and_or (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_fetch_and_or (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-4.c b/gcc/testsuite/gcc.target/mips/fix-r10000-4.c
new file mode 100644
index 00000000000..0c962ee267f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-4.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_fetch_and_and (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_fetch_and_and (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_fetch_and_and (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-5.c b/gcc/testsuite/gcc.target/mips/fix-r10000-5.c
new file mode 100644
index 00000000000..15a0704f2c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-5.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_fetch_and_xor (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_fetch_and_xor (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_fetch_and_xor (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-6.c b/gcc/testsuite/gcc.target/mips/fix-r10000-6.c
new file mode 100644
index 00000000000..275136957c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-6.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_fetch_and_nand (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_fetch_and_nand (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_fetch_and_nand (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-7.c b/gcc/testsuite/gcc.target/mips/fix-r10000-7.c
new file mode 100644
index 00000000000..bbe985695da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-7.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_add_and_fetch (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_add_and_fetch (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_add_and_fetch (z, 42);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-8.c b/gcc/testsuite/gcc.target/mips/fix-r10000-8.c
new file mode 100644
index 00000000000..6e990a63fa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-8.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z, int amt)
+{
+ return __sync_sub_and_fetch (z, amt);
+}
+
+NOMIPS16 short
+f2 (short *z, short amt)
+{
+ return __sync_sub_and_fetch (z, amt);
+}
+
+NOMIPS16 char
+f3 (char *z, char amt)
+{
+ return __sync_sub_and_fetch (z, amt);
+}
diff --git a/gcc/testsuite/gcc.target/mips/fix-r10000-9.c b/gcc/testsuite/gcc.target/mips/fix-r10000-9.c
new file mode 100644
index 00000000000..8373c42d949
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fix-r10000-9.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-mips-options "-O2 -march=mips4 -mfix-r10000" } */
+/* { dg-final { scan-assembler-times "\tbeql\t" 3 } } */
+
+NOMIPS16 int
+f1 (int *z)
+{
+ return __sync_or_and_fetch (z, 42);
+}
+
+NOMIPS16 short
+f2 (short *z)
+{
+ return __sync_or_and_fetch (z, 42);
+}
+
+NOMIPS16 char
+f3 (char *z)
+{
+ return __sync_or_and_fetch (z, 42);
+}